Day23:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

目录

具体安全知识点

身份验证-Cookie使用

身份验证-Session使用

唯一性判断-Token使用

总结

源码

思维导图


PHP知识点:

功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等

技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;

技术:JS&CSS混用,Cookie,Session操作,MVC架构,ThinkPHP引用等。

具体安全知识点

Cookie和Session都是用来在Web应用程序中跟踪用户状态的机制
1、存储位置不同:
Cookie是存储在客户端(浏览器)上的,而Session是存储在服务器端的。
2、安全性不同:
Cookie存储在客户端上,可能会被黑客利用窃取信息,而Session存储在服务器上,更加安全。
3、存储容量不同:
Cookie的存储容量有限,一般为4KB,而Session的存储容量理论上没有限制,取决于服务器的硬件和配置。
4、生命周期不同:
Cookie可以设置过期时间,即便关闭浏览器或者重新打开电脑,Cookie仍然存在,直到过期或者被删除。而Session一般默认在浏览器关闭后就会过期。
5、访问方式不同:
Cookie可以通过JavaScript访问,而Session只能在服务器端进行访问。
6、使用场景不同:
Cookie一般用于存储小型的数据,如用户的用户名和密码等信息。而Session一般用于存储大型的数据,如购物车、登录状态等信息。


总之,Cookie和Session都有各自的优缺点,选择使用哪一种方式,取决于具体的应用场景和需求。一般来说,如果需要存储敏感信息或者数据较大,建议使用Session;如果只需要存储少量的数据,并且需要在客户端进行访问,可以选择使用Cookie。

在Web应用程序中,使用token和不使用token的主要差异在于身份验证和安全性。
1.身份验证:采用token机制的Web应用程序,用户在登录成功后会收到一个token,这个token可以在每次请求时发送给服务器进行身份验证。而不采用token机制的Web应用程序,一般会使用session机制来保存用户登录状态,服务器会在用户登录成功后创建一个session,之后的每个请求都需要在HTTP头中附带这个session ID,以便服务器能够验证用户身份。
2、安全性:采用token机制的Web应用程序,在服务器上不会存储用户的登录状态,只需要存储token即可。因此,即使token被盗取,黑客也无法获得用户的密码或者其他敏感信息。而不采用token机制的Web应用程序,一般会在服务器上存储用户的登录状态,因此如果服务器被黑客攻击,黑客可能会获得用户的敏感信息。
3、跨域访问:采用token机制的Web应用程序,在跨域访问时,可以使用HTTP头中的Authorization字段来传递token信息,方便实现跨域访问。而不采用token机制的Web应用程序,在跨域访问时,需使用cookie或session来传递用户身份信息,比较麻烦。
总之,采用token机制可以提高Web应用程序的安全性,并且方便实现跨域访问。不过,使用token机制也需要开发者自己来实现身份验证和token的生成和验证,相对来说比较复杂。而不采用token机制,使用session机制则相对简单,但是安全性相对较低。因此,具体采用哪种机制,需要根据实际情况进行权衡和选择。

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

身份验证-Cookie使用

生成cookie的原理图过程:见图

1、客户端向服务器发送HTTP请求。

2、服务器检查请求头中是否包含cookie信息。

3、如果请求头中包含cookie信息,则服务器使用该cookie来识别客户端,否则服务器将生成一个新的cookie。

4、服务器在响应头中设置cookie信息并将其发送回客户端。

5、客户端接收响应并将cookie保存在本地。

6、当客户端发送下一次HTTP请求时,它会将cookie信息附加到请求头中。

7、服务器收到请求并检查cookie的有效性。

8、如果cookie有效,则服务器响应请求。否则,服务器可能会要求客户端重新登录。

setcookie(): 设置一个cookie并发送到客户端浏览器。

unset(): 用于删除指定的cookie。

Cookie安全:

信息泄露:如果Cookie中包含敏感信息(如用户ID、密码等),攻击者可以通过窃取Cookie来获取这些敏感数据。为了防止信息泄露,应确保敏感信息在传输和存储过程中进行加密,并使用安 全的传输协议(如HTTPS)来保护Cookie的传输过程。


跨站点脚本攻击(XSS):攻击者可以通过在Web应用程序中注入恶意脚本来获取用户的Cookie。为了防止XSS攻击,开发人员应对用户输入进行正确的验证和过滤,并对输出进行适当的转义,以防止恶意脚本的注入。


跨站点请求伪造(CSRF):攻击者可以通过欺骗用户访问恶意网站来利用用户的身份进行非法操作。为了防止CSRF攻击,可以使用随机生成的令牌(CSRF令牌)来验证每个请求的合法性,并确保令牌在每个请求中都是唯一且难以预测的。


会话劫持:攻击者可以通过窃取用户的会话Cookie来冒充用户身份。为了防止会话劫持,可以通过使用安全标志(如"Secure"和"HttpOnly")来限制Cookie的使用范围,并在会话身份验证上使用额外的保护措施,如双因素身份验证。


不安全的存储:如果Cookie存储在用户计算机上的不安全位置,如明文存储或不加密的存储,攻击者可以轻易地访问和修改Cookie。为了保护Cookie的存储,应将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原理:

1、客户端向服务器发送HTTP请求。
2、服务器为客户端生成一个唯一的session ID,并将其存储在服务器端的存储器中(如文件、数据库等)。
3、服务器将生成的session ID作为一个cookie发送给客户端。
4、客户端将session ID保存为一个cookie,通常是在本地浏览器中存储。
5、当客户端在发送下一次HTTP请求时,它会将该cookie信息附加到请求头中,以便服务器可以通过该session ID来识别客户端。
6、服务器使用session ID来检索存储在服务器端存储器中的与该客户端相关的session数据,从而在客户端和服务器之间共享数据。

session_start(): 启动会话,用于开始或恢复一个已经存在的会话。
$_SESSION: 用于存储和访问当前会话中的所有变量。
session_destroy(): 销毁当前会话中的所有数据。
session_unset(): 释放当前会话中的所有变量。

Session安全:

会话劫持:会话劫持是指攻击者通过窃取合法用户的会话标识符(如会话ID或令牌)来冒充用户身份。为了防止会话劫持,应采取以下措施:

  • 使用随机生成的、复杂的会话标识符,使其难以猜测。
  • 在会话标识符上实施安全标志,如"Secure"和"HttpOnly",以限制Cookie的使用范围。
  • 在用户身份验证过程中使用额外的保护措施,如双因素身份验证。

会话固定攻击:会话固定攻击是指攻击者通过将自己的会话标识符强制应用于目标用户的会话来控制目标用户的会话。为了防止会话固定攻击,应采取以下措施:

  • 在用户认证之前生成新的会话标识符,而不是在认证后重新使用现有的会话标识符。
  • 在用户身份验证之前销毁旧会话,以确保新会话的安全性。

跨站点脚本攻击(XSS):XSS攻击可以窃取用户会话数据或以其他方式干扰会话。为了防止XSS攻击,应采取以下措施:

  • 对用户输入进行正确的验证和过滤,以防止恶意脚本的注入。
  • 对输出进行适当的转义,以防止恶意脚本在浏览器中执行。

跨站点请求伪造(CSRF):CSRF攻击可以利用用户的身份执行未经授权的操作。为了防止CSRF攻击,应采取以下措施:

  • 使用随机生成的、唯一的CSRF令牌来验证每个请求的合法性。
  • 将CSRF令牌嵌入到表单中,并在每个请求中验证令牌的有效性。

会话超时和注销:应设定适当的会话超时时间,以确保长时间不活动的会话被及时注销。同时,提供明确的注销功能,使用户可以主动终止会话。

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生成原理:

1、生成Token并将其存储在Session
2、生成Token并将其绑定在Cookie触发
3、尝试登录表单中带入Token验证逻辑
4、思考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 '登录失败!';
    }
}
?>

思维导图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436750.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云渲染平台都开始涨价了?2024年性价比高的云渲染平台推荐

最近部分云渲染平台开始涨价&#xff0c;不论是通过调整机器性能&#xff0c;还是直接提价&#xff0c;都会对成本产生影响。这对已经习惯了平台价格的用户来说&#xff0c;并不是一件好事。这里举一些例子&#xff1a; 比如平台A&#xff0c;原“首小时渲染0.66元模式”已经下…

信号处理--基于EEG脑电信号处理研究概述

目录 前言 EEG特点 EEG预处理 EEG通道选择 EEG数据增强 EEG 维度降低 EEG特征提取 传统特征提取 深度学习自动提取特征 未来展望 创新的预处理方法 跨被试性能问题 模型融合 参考 前言 脑电信号&#xff08;EEG&#xff09;因其安全性、便携性、易用性、高时间分…

【C++】C/C++内存管理详解

个人主页 &#xff1a; zxctscl 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 目录 1. 前言2. C/C内存分布3. C语言中动态内存管理方式4. C中动态内存管理4.1 new/delete操作内置类型4.2 new和delete操作自定义类型 5. operator new与operator delete函数5.1 oper…

2024 年 AI 辅助研发趋势

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…

章鱼网络进展月报 | 2024.2.1-2.29

章鱼网络大事摘要 1、Omnity 完成了核心组件的原型开发&#xff0c;正在测试&#xff0c;未来将首先支持 Runes 资产跨链。 2、$NEAR Restaking 质押总量超过400万美元。 3、章鱼网络受邀参加 ETHDenver 2024&#xff0c;并且与 ICP 共同组织活动&#xff0c;介绍 Omnity 的…

多线程:线程池

线程池 认识线程池 什么是线程池 线程池就是一个可以复用线程的技术。 不使用线程池的问题 用户每发起一个请求&#xff0c;后台就需要创建一个新线程来处理&#xff0c;下次新任务来了肯定又要创建新线程处理的&#xff0c;而创建新线程的开销是很大的&#xff0c;并且请…

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)

引言 其实C基础语法基本上已经学完&#xff0c;早就想开始写C的博客了&#xff0c;却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的&#xff0c;后来考虑了一下还是算了&#xff0c;等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…

java IO 02 IO接口

01.定义 02.IO中的输入和输出的划分 03.流的分类 IO流的所有类中&#xff0c;最先分野的是字节流和字符流。 字节流包括&#xff1a;输入流和输出流 InputStream public abstract class InputStream implements Closeable { }OutputStream public abstract class OutputSt…

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…

Node.js概述与安装和运行

Node.js概述与安装和运行 一、Node.js1.Node.js概述2.Node.js官网2.Node.js 各系统版本下载网址3.1 Node.js Windows下载网址 二、Node.js安装1.1 打开Node.js下载网址1.2 安装Node.js1.3 同意协议1.4 安装目录1.5 自定义安装1.6 本机模块工具1.7 进行安装Node.js1.8 安装完成1…

NLP自然语言——基础

一、介绍 1、概念 NLP&#xff08;Natural Language Processing&#xff0c;自然语言处理&#xff09;是计算机科学领域以及人工智能领域的一个重要的研究方向&#xff0c;它研究用计算机来处理、理解以及运用人类语言&#xff08;如中文、英文等&#xff09;&#xff0c;达到…

Java 解决异步 @Async 失效问题

1.问题描述 使用Async进行异步处理时&#xff0c;异步没有生效 2.原因分析 经过排查后发现是因为使用Async的方法没有跨2个Service导致的 错误示例 控制器接口 > 直接调用 custAdminService.importCBuy() 3.解决方案 Controller接口不变&#xff0c;多添加一层Service&a…

内网渗透NC木马后门复现

本文章仅用于信息安全学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若读者因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与作者无关。 首先假设已经通过Kail成功入侵靶机&#xff1a;https://blog.csdn.net/mshxuyi/article/details/1…

使用cmd命令运行java

1.普通项目(不带lib文件夹) 1.在桌面上建一个名为com的文件夹&#xff0c;在文件夹中用记事本写两个类文件&#xff0c;后缀改为.java。两个类文件的内容如下图所示&#xff1a; 2.使用javac命令编译主函数&#xff0c;命令行为javac TestMain.java。结果可以看到自动生成了两…

Linux第68步_旧字符设备驱动的一般模板

file_operations结构体中的函数就是我们要实现的具体操作函数。 注意&#xff1a; register_chrdev()和 unregister_chrdev()这两个函数是老版本驱动使用的。现在新字符设备驱动已经不再使用这两个函数&#xff0c;而是使用Linux内核推荐的新字符设备驱动API函数。 1、创建C…

zerotier局域网组建 笔记

背景 家里的windows电脑&#xff1a;home-win10-pc 家里的windows电脑上vmware运行的ubuntu虚拟机&#xff1a;home-ubuntu-vm 公司的mac电脑&#xff1a;company-mac-pc 由于xxx需求&#xff0c;需要组建一个局域网&#xff0c;前东家都是用的zerotier&#xff0c;出于路径依…

代码学习记录10

随想录日记part10 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.03 主要内容&#xff1a;今天的主要内容是深入了解数据结构中栈和队列&#xff0c;并通过三个 l e e t c o d e leetcode leetcode 题目深化认识。 20. 有效的括号1047. 删除字符串中的所有…

FL Studio怎么分轨导出音频文件 FL Studio轨道怎么合并 音乐编曲软件推荐 FL Studio下载

对于现在的编曲人来说&#xff0c;熟练掌握各类编曲软件已经是硬性要求了。掌握编曲软件的使用方法需要我们付出一些学习时间&#xff0c;例如编曲软件中各个轨道的拆分与合并等等&#xff0c;这些都是非常实用的编曲软件使用技巧。今天我就以FL Studio举例&#xff0c;向大家展…

轻薄蓝牙工牌室内人员定位应用

在现代化企业管理的背景下&#xff0c;轻薄蓝牙工牌人员定位应用逐渐崭露头角&#xff0c;成为提升企业效率和安全性的重要工具。本文将从轻薄蓝牙工牌的定义、特点、应用场景以及未来发展趋势等方面&#xff0c;对其进行全面深入的探讨。 一、轻薄蓝牙工牌的定义与特点 轻薄…

今日arXiv最热大模型论文:哈工深新研究发现!无需额外资源,SelectIT方法助力大语言模型精准调优

在当今的人工智能领域&#xff0c;大语言模型&#xff08;LLMs&#xff09;已经成为了研究的热点&#xff0c;它们在理解指令和解决复杂问题方面展现出了令人印象深刻的能力。然而&#xff0c;要想进一步提升这些模型的性能&#xff0c;指令调优&#xff08;Instruction Tuning…