0
点赞
收藏
分享

微信扫一扫

每日OJ题_链表②_力扣24. 两两交换链表中的节点

草原小黄河 03-08 12:00 阅读 2
Web安全

目录

具体安全知识点

身份验证-Cookie使用

身份验证-Session使用

唯一性判断-Token使用

总结

源码

思维导图


具体安全知识点

下面的实验都是使用PHP开发的,php代码执行在后端,只有除此之外的代码会返回给浏览器

身份验证-Cookie使用

setcookie()有四个参数,分别是:Cookie名称,Cookie值,过期时间,Cookie在浏览器的存储路径("/",标识根目录,该Cookie在整个网站都可以访问)。

创建admin-c.php登陆页面

打开项目admin目录分别创建三个文件:

  • admin-c.php登陆文件
  • index-c.php登录成功的首页文件
  • logout-c.php登出文件

使用chtgpt生成一个后台登录的html界面

  • 你需要在实际应用中将登录表单的 action属性指向后台处理登录的脚本(例如 login.php)由于当前就是登录文件为空即可<form action="" method="post">

进行编写登录的程序

1、接收输入账号密码

2、判断账号密码是否正确

  • 需要构建数据库admin【username,password】
  • 输入默认值【admin,123456】(当登陆成功的时候数据显示的,登录不成功数据显示为0)
  • 加入判断是否是POST请求,来防止一直提示登陆失败
  • 加入判断行数是否大于0来判断是否登录成功
// 判断请求是否为 POST
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // 检查查询结果行数是否大于 0
    if (mysqli_num_rows($data) > 0) {

3.正确后生成cookie进行保存

设置cookie值(过期时间,依据用户名密码等生成)

$expire = time() + 60 * 60 * 24 * 30; // 设置 Cookie 过期时间为一个月后
        setcookie('username', $user, $expire, '/'); // 设置用户名 Cookie
        setcookie('password', $pass, $expire, '/'); // 设置密码 Cookie

4.错误的账户密码进行提示*

5.跳转至成功页面,进行跳转到登录成功页面

// 重定向到 index-c.php 页面
        header('Location: index-c.php');
				exit();  // 终止脚本执行

创建admin-c.php登陆成功的首页文件,创建logout-c.php登出文件

构建登入成功的HTMl页面,并输出当前登录的用户

  • 给出退出登录的选项,如果触发则跳转到登录页面
  • 登陆前没有cookie是不显示任何用户名的,登陆后显示出用户名
  • 需要加入判断如果获取的cookie值,和数据库中对应的数据值不同,则要跳转到登录页面,使之继续登录,直至相符
<?php
**//登录成功的首页文件
if ($_COOKIE['username']!='admin'and$_COOKIE['password']!='123456')
    // 重定向到 index-c.php 页面
    header('Location: index-c.php');
?>**
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
**<p>欢迎您,<?php echo $_COOKIE['username']; ?>!</p>
<p><a href="logout-c.php">退出登录</a></p>**
</body>
</html>

构建登出成功的代码,将cookie值默认为空,并跳转至登陆页面

<?php

**setcookie('username', '', time() - 3600, '/');
setcookie('password', '', time() - 3600, '/');
// 跳转到登录页面
header('Location: admin-c.php');**
exit;
?>

admin/admin-c.php:登录验证并且成功后跳转到admin/index-c.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后台登录</title>
    <style>
        body {
            background-color: #f1f1f1;
        }
        .login {
            width: 400px;
            margin: 100px auto;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
            padding: 30px;
        }
        .login h2 {
            text-align: center;
            font-size: 2em;
            margin-bottom: 30px;
        }
        .login label {
            display: block;
            margin-bottom: 20px;
            font-size: 1.2em;
        }
        .login input[type="text"], .login input[type="password"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 1.2em;
            margin-bottom: 20px;
        }
        .login input[type="submit"] {
            background-color: #2ecc71;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 1.2em;
            cursor: pointer;
        }
        .login input[type="submit"]:hover {
            background-color: #27ae60;
        }
    </style>
</head>
<body>
<div class="login">
    <h2>后台登录</h2>
    <form action="" method="post">
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" required>
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" required>
        <input type="submit" value="登录">
    </form>
</div>
</body>
</html>

<?php
include '../config.php';
//登录文件
/*
 * 1、接受输入的帐号密码
 * 2、判断帐号密码正确性
 * 3、正确后生成的cookie进行保存
 * 3、1错误的帐号密码就进行提示
 * 4、跳转至成功登录的页面
 */

//1、接受输入的帐号密码
$user=$_POST['username'];
$pass=$_POST['password'];

//2、判断帐号密码正确性
//连接数据库 进行数据库查询将数据进行对比
$sql="select * from admin where username='$user' and password='$pass';";
$data=mysqli_query($con,$sql);
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // 判断用户登录成功
    // 检查查询结果行数是否大于 0
    if(mysqli_num_rows($data) > 0){
        $expire = time() + 60 * 60 * 24 * 30; // 一个月后过期
        setcookie('username', $user, $expire, '/');  //
        setcookie('password', $pass, $expire, '/');
        //echo '<script>alert("登录成功!")</script>';
        // 重定向到 index-c.php 页面
        header('Location: index-c.php');
        exit(); // 终止脚本运行
    }else{
        //判断用户登录失败
        echo '<script>alert("登录失败!")</script>';
    }
}

admin/index-c.php:检测未授权访问,并跳转登录页面

<?php

// 验证cookie不正确
if($_COOKIE['username']!='admin' and $_COOKIE['password']!='123456'){
    header('Location: admin-c.php');
}

?>


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
<p>欢迎您,<?php echo $_COOKIE['username']; ?>!</p>
<p><a href="logout-c.php">退出登录</a></p>
</body>
</html>

admin/login-c.php:退出登录

<?php

setcookie('username', '', time() - 3600, '/');
setcookie('password', '', time() - 3600, '/');
// 跳转到登录页面
header('Location: admin-c.php');
exit;
?>

身份验证-Session使用

Session存储路径:PHP.INI中session.save_path设置路径

在php.ini中设置session存储路径(服务端)

当登录成功后,生成如下文件:

内如如下:

username|s:5:"admin";password|s:6:"123456";

sesion被存储在Cookie里

退出登录后,服务端删除/tmp/tmp下的session文件,浏览器session失效

PHPSEDDID的值就是服务端文件sess_后缀,服务端上这个文件存储铭文信息。服务端是通过这个字符串识别的。

为什么安全?用户退出登录即失效,即使黑客抓到session也没用。

唯一性判断-Token使用

创建Token文件:Token.php,Token_check.php;前端页面类似,复制过来,修改一下有关toke代码

<div class="login">
    <h2>后台登录</h2>
    **<!-- 提交表单到 "token_check.php",使用 POST 方法 -->
    <form action="token_check.php" method="post">
        <!-- 隐藏域用于存储 CSRF token -->
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ; ?>">**
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" required>
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" required>
        <input type="submit" value="登录">
    </form>
</div>

Toke生成的代码

每次token随表单提交后都需要重置以保持token的唯一性。

<?php
// 生成Token并将其存储在Session中
**session_start();**
//1.因为是用的session维持会话,token已经绑定到下面的表单了
//2.token,生成之后直接存到session里,主要是方便重置token,
//**每次token随表单提交后都需要重置以保持token的唯一性。**
**$_SESSION['token'] = bin2hex(random_bytes(16));**
?>

Token_check.php,完成有关toke检验的代码

登录成功,token值保存在session中

<?php
session_start();
**// 从 POST 请求中获取 token,如果不存在则设为空字符串
$token = $_POST['token'] ?? '';**

**if ($token !== $_SESSION['token']) {
    // token不匹配,禁止访问
    header('HTTP/1.1 403 Forbidden');
    // 生成新的 token
    $_SESSION['token'] = bin2hex(random_bytes(16));
    // 输出访问被拒绝的信息
    echo 'Access denied';
    // 终止脚本执行
    exit;**
}else{
    **// 生成新的 token
    $_SESSION['token'] = bin2hex(random_bytes(16));
    // 检查用户名和密码是否匹配
    if($_POST['username']=='admin' && $_POST['password']=='123456'){
        echo '登录成功!';**
        // 输出管理员访问信息
        echo '你是管理员可以访问文件管理页面!';
    }else{
        echo '登录失败!';
    }
}
?>

访问token.php,php代码在后端被执行,生成一个session给浏览器作为CooKie

生成一个token值,存储在服务端的session文件里

同时也保存在浏览器里

输入账号密码提交

登录成功

Cookie的PHPSESSID不变

但是token值变了,服务器上的

刷新再次访问,还是上一次的token,登录失败

token为什么具有唯一性,就是每次数据包交互之后token就会改变,流量包里的token永远是上一次的。

总结

Cookie:一旦生成就会作为身份凭据在有效期内不会再改变

攻击者一旦获得Cookie就能以这个凭据登录

Session:登录成功后,就会生成B/S之间的会话

  • 浏览器:PHPSESSID:session(字符串) 作为Cookie
  • 服务端:session_session文件,存储用户账号密码

攻击者获得Session后却不能直接登录,因为这只是一个服务端对用户的标识,还需要输入密码正确才行。

Token:token在服务端,浏览器都有存储,服务端保存在会话里。每次数据交互后都改变。

攻击者从流量上获得的token永远是上一次的

源码

admin-c.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后台登录</title>
    <style>
        body {
            background-color: #f1f1f1;
        }
        .login {
            width: 400px;
            margin: 100px auto;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
            padding: 30px;
        }
        .login h2 {
            text-align: center;
            font-size: 2em;
            margin-bottom: 30px;
        }
        .login label {
            display: block;
            margin-bottom: 20px;
            font-size: 1.2em;
        }
        .login input[type="text"], .login input[type="password"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 1.2em;
            margin-bottom: 20px;
        }
        .login input[type="submit"] {
            background-color: #2ecc71;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 1.2em;
            cursor: pointer;
        }
        .login input[type="submit"]:hover {
            background-color: #27ae60;
        }
    </style>
</head>
<body>
<div class="login">
    <h2>后台登录</h2>
    <form action="" method="post">
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" required>
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" required>
        <input type="submit" value="登录">
    </form>
</div>
</body>
</html>

<?php
include '../config.php';
//登录文件
/*
 * 1、接受输入的帐号密码
 * 2、判断帐号密码正确性
 * 3、正确后生成的cookie进行保存
 * 3、1错误的帐号密码就进行提示
 * 4、跳转至成功登录的页面
 */

//1、接受输入的帐号密码
$user=$_POST['username'];
$pass=$_POST['password'];

//2、判断帐号密码正确性
//连接数据库 进行数据库查询将数据进行对比
$sql="select * from admin where username='$user' and password='$pass';";
$data=mysqli_query($con,$sql);
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // 判断用户登录成功
    // 检查查询结果行数是否大于 0
    if(mysqli_num_rows($data) > 0){
        $expire = time() + 60 * 60 * 24 * 30; // 一个月后过期
        setcookie('username', $user, $expire, '/');  //
        setcookie('password', $pass, $expire, '/');
        //echo '<script>alert("登录成功!")</script>';
        // 重定向到 index-c.php 页面
        header('Location: index-c.php');
        exit(); // 终止脚本运行
    }else{
        //判断用户登录失败
        echo '<script>alert("登录失败!")</script>';
    }
}


index-c.php

<?php

// 验证cookie不正确
if($_COOKIE['username']!='admin' and $_COOKIE['password']!='123456'){
    header('Location: admin-c.php');
}

?>


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
<p>欢迎您,<?php echo $_COOKIE['username']; ?>!</p>
<p><a href="logout-c.php">退出登录</a></p>
</body>
</html>

logout-c.php

<?php

setcookie('username', '', time() - 3600, '/');
setcookie('password', '', time() - 3600, '/');
// 跳转到登录页面
header('Location: admin-c.php');
exit;
?>

admin-s.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后台登录</title>
    <style>
        body {
            background-color: #f1f1f1;
        }
        .login {
            width: 400px;
            margin: 100px auto;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
            padding: 30px;
        }
        .login h2 {
            text-align: center;
            font-size: 2em;
            margin-bottom: 30px;
        }
        .login label {
            display: block;
            margin-bottom: 20px;
            font-size: 1.2em;
        }
        .login input[type="text"], .login input[type="password"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 1.2em;
            margin-bottom: 20px;
        }
        .login input[type="submit"] {
            background-color: #2ecc71;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 1.2em;
            cursor: pointer;
        }
        .login input[type="submit"]:hover {
            background-color: #27ae60;
        }
    </style>
</head>
<body>
<div class="login">
    <h2>后台登录</h2>
    <form action="" method="post">
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" required>
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" required>
        <input type="submit" value="登录">
    </form>
</div>
</body>
</html>
<?php
include '../config.php';
//登录文件-采用session验证

//1、接受输入的帐号密码
$user=$_POST['username'];
$pass=$_POST['password'];
$sql="select * from admin where username='$user' and password='$pass';";
$data=mysqli_query($con,$sql);
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // 登录密码可以查到,及正确,生成session
    if(mysqli_num_rows($data) > 0){
        session_start();  // 启动会话,用于开始或恢复一个已经存在的会话。
        // $_SESSION: 用于存储和访问当前会话中的所有变量。
        $_SESSION['username']=$user;
        $_SESSION['password']=$pass;
        header('Location: index-s.php');
        exit();
    }else{
        echo '<script>alert("登录失败!")</script>';
    }

}

index-s.php

<?php
//登录成功首页文件-采用session验证
//判断省去了数据库查询获取帐号密码的操作 直接赋值
session_start();
if($_SESSION['username']!='admin' && $_SESSION['password']!='123456'){
    header('Location: admin-s.php');
}

?>

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
<p>欢迎您,<?php echo $_SESSION['username']; ?>!</p>
<p><a href="logout-s.php">退出登录</a></p>
</body>
</html>

logout-s.php

<?php
// 开始会话
session_start();

// 清除 SESSION 变量,并销毁会话
session_unset(); // session_destroy(): 销毁当前会话中的所有数据。
session_destroy(); // 释放当前会话中的所有变量。

// 重定向到登录页面
header('Location: admin-s.php');
exit;
?>

token.php

<?php
// 生成Token并将其存储在Session中
session_start();


//1.因为是用的session维持会话,token已经绑定到下面的表单了
//2.token,生成之后直接存到session里,主要是方便重置token,
//每次token随表单提交后都需要重置以保持token的唯一性。

$_SESSION['token'] = bin2hex(random_bytes(16));


?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后台登录</title>
    <style>
        body {
            background-color: #f1f1f1;
        }
        .login {
            width: 400px;
            margin: 100px auto;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
            padding: 30px;
        }
        .login h2 {
            text-align: center;
            font-size: 2em;
            margin-bottom: 30px;
        }
        .login label {
            display: block;
            margin-bottom: 20px;
            font-size: 1.2em;
        }
        .login input[type="text"], .login input[type="password"] {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 1.2em;
            margin-bottom: 20px;
        }
        .login input[type="submit"] {
            background-color: #2ecc71;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 1.2em;
            cursor: pointer;
        }
        .login input[type="submit"]:hover {
            background-color: #27ae60;
        }
    </style>
</head>
<body>
<div class="login">
    <h2>后台登录</h2>
    <form action="token_check.php" method="post">
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ; ?>">
        <label for="username">用户名:</label>
        <input type="text" name="username" id="username" required>
        <label for="password">密码:</label>
        <input type="password" name="password" id="password" required>
        <input type="submit" value="登录">
    </form>
</div>
</body>
</html>

token_check.php

<?php
session_start();
// 从 POST 请求中获取 token,如果不存在则设为空字符串
$token = $_POST['token'] ?? '';

if ($token !== $_SESSION['token']) {
    // token不匹配,禁止访问
    header('HTTP/1.1 403 Forbidden');
    // 生成新的 token
    $_SESSION['token'] = bin2hex(random_bytes(16));
    // 输出访问被拒绝的信息
    echo 'Access denied';
    // 终止脚本执行
    exit;
}else{
    // 生成新的 token
    $_SESSION['token'] = bin2hex(random_bytes(16));
    // 检查用户名和密码是否匹配
    if($_POST['username']=='admin' && $_POST['password']=='123456'){
        echo '登录成功!';
        // 输出管理员访问信息
        echo '你是管理员可以访问文件管理页面!';
    }else{
        echo '登录失败!';
    }
}
?>

思维导图

举报

相关推荐

0 条评论