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

news2024/10/7 16:07:37

第二十三天

在这里插入图片描述

一、PHP后台身份验证模块实现

image-20240415113234324

image-20240415113244797

二、Cookie&Session技术&差异

1.生成cookie的原理图过程:见上图

  1. 客户端向服务器发送HTTP请求。
  2. 服务器检查请求头中是否包含cookie信息。
  3. 如果请求头中包含cookie信息,则服务器使用该cookie来识别客户端,否则服务器将生成一个新的cookie。
  4. 服务器在响应头中设置cookie信息并将其发送回客户端。
  5. 客户端接收响应并将cookie保存在本地。
  6. 当客户端发送下一次HTTP请求时,它会将cookie信息附加到请求头中。
  7. 服务器收到请求并检查cookie的有效性。
  8. 如果cookie有效,则服务器响应请求。否则,服务器可能会要求客户端重新登录。

2.session原理

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

3.函数解释

1.cookie

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

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

2.session

session_start(): 启动会话,用于开始或恢复一个已经存在的会话。

$_SESSION: 用于存储和访问当前会话中的所有变量。

session_destroy(): 销毁当前会话中的所有数据。

session_unset(): 释放当前会话中的所有变量。

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

3.安全知识

Cookie和Session都是用来在Web应用程序中跟踪用户状态的机制

1.存储位置不同:

Cookie是存储在客户端(浏览器)上的,而Session是存储在服务器端的。

2.安全性不同:

Cookie存储在客户端上,可能会被黑客利用窃取信息,而Session存储在服务器上,更加安全。

3.存储容量不同:

Cookie的存储容量有限,一般为4KB,而Session的存储容量理论上没有限制,取决于服务器的硬件和配置。

4.生命周期不同:

Cookie可以设置过期时间,即便关闭浏览器或者重新打开电脑,Cookie仍然存在,直到过期或者被删除。而Session一般默认在浏览器关闭后就会过期。

5.访问方式不同:

Cookie可以通过JavaScript访问,而Session只能在服务器端进行访问。

6.使用场景不同:

Cookie一般用于存储小型的数据,如用户的用户名和密码等信息。而Session一般用于存储大型的数据,如购物车、登录状态等信息。

7.总结:

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


三、Token数据包唯一性应用场景

1.token原理

  1. 随机生成Token并将其存储在Session
  2. 生成Token并将其绑定在Cookie触发
  3. 尝试登录表单中带入Token验证逻辑
  4. 思考Token安全特性

2.安全知识

在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来传递用户身份信息,比较麻烦。

4.总结

总之,采用token机制可以提高Web应用程序的安全性,并且方便实现跨域访问。不过,使用token机制也需要开发者自己来实现身份验证和token的生成和验证,相对来说比较复杂。而不采用token机制,使用session机制则相对简单,但是安全性相对较低。因此,具体采用哪种机制,需要根据实际情况进行权衡和选择。


四.环境复现

1.用cookie做后台身份验证

1.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);

// 如果是通过 POST 方法提交的表单
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // 判断用户登录成功
    if (mysqli_num_rows($data) > 0) {
        $expire = time() + 60 * 60 * 24 * 30; // 一个月后过期
        setcookie('username', $user, $expire, '/');
        setcookie('password', $pass, $expire, '/');
        //echo '<script>alert("登录成功!")</script>';
        header('Location: index-c.php');
        exit();
    } else {
        // 判断用户登录失败
        echo '<script>alert("登录失败!")</script>';
    }
}
?>

2.index-c.php源码
<?php
// 检查用户是否登录,如果未登录则重定向到登录页面
if ($_COOKIE['username'] !== 'admin' || $_COOKIE['password'] !== '123456') {
    header('Location: admin-c.php');
    exit(); // 终止脚本执行,确保页面重定向生效
}
?>

<!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>

3.logout-c.php源码
<?php
// 删除存储在客户端的用户凭据的 Cookie
setcookie('username', '', time() - 3600, '/');
setcookie('password', '', time() - 3600, '/');

// 跳转到登录页面
header('Location: admin-c.php');
exit; // 终止脚本执行,确保页面重定向生效
?>


2.用session做后台身份验证

1.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'];

// 2、判断帐号密码正确性
// 连接数据库 进行数据库查询将数据进行对比
$sql = "select * from admin where username='$user' and password='$pass';";
$data = mysqli_query($con, $sql);

// 如果是通过 POST 方法提交的表单
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // 判断用户登录成功
    if (mysqli_num_rows($data) > 0) {
        // 启动会话
        session_start();
        // 将用户名和密码存储到会话中
        $_SESSION['username'] = $user;
        $_SESSION['password'] = $pass;
        // 跳转到成功登录的页面
        header('Location: index-s.php');
        exit(); // 终止脚本执行,确保页面重定向生效
    } else {
        // 判断用户登录失败
        echo '<script>alert("登录失败!")</script>';
    }
}
?>

2.index-s.php源码

<?php
// 登录成功首页文件-采用session验证

// 启动会话
session_start();

// 如果会话中的用户名和密码与预期不符,则重定向到登录页面
if ($_SESSION['username'] !== 'admin' || $_SESSION['password'] !== '123456') {
    header('Location: admin-s.php');
    exit(); // 终止脚本执行,确保页面重定向生效
}
?>

<!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>
3.logout-s.php源码
<?php
// 开始会话
session_start();

// 清除 SESSION 变量,并销毁会话
session_unset(); // 清除所有的会话变量
session_destroy(); // 销毁会话

// 重定向到登录页面
header('Location: admin-s.php');
exit; // 终止脚本执行,确保页面重定向生效
?>

3.用token做用户登录判断

1.token.php源码
<?php
// 开始会话
session_start();

// 生成Token并将其存储在Session中
// 生成一个16字节的随机Token,并将其转换为十六进制表示存储在Session中
$_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">
        <!-- 将生成的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>
</body>
</html>

2.token_check.php源码

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

// 获取POST请求中的token,如果不存在则将其设置为空字符串
$token = $_POST['token'] ?? '';

// 检查POST请求中的token是否与会话中的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匹配,则重新生成一个新的token并存储在会话中,以确保安全性
    $_SESSION['token'] = bin2hex(random_bytes(16));
    
    // 检查用户名和密码是否为管理员的凭证
    if ($_POST['username'] == 'admin' && $_POST['password'] == '123456') {
        echo '登录成功!'; // 输出登录成功的消息
        echo '你是管理员可以访问文件管理页面!'; // 输出管理员特权消息
    } else {
        echo '登录失败!'; // 输出登录失败的消息
    }
}
?>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++奇迹之旅:构造函数和析构函数

文章目录 &#x1f4dd;类的6个默认成员函数&#x1f320; 构造函数&#x1f309; 概念&#x1f309;特性&#x1f309;三种默认构造函数 &#x1f320; 析构函数&#x1f320; 特性&#x1f6a9;总结 &#x1f4dd;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0…

OpenHarmony其他工具类—lua

简介 Lua是一种功能强大、高效、轻量级、可嵌入的脚本语言。 支持过程编程、面向对象编程、函数编程、数据驱动编程和数据描述。 下载安装 直接在OpenHarmony-SIG仓中搜索lua并下载。 使用说明 以OpenHarmony 3.1 Beta的rk3568版本为例 将下载的lua库代码存在以下路径&#…

javase__进阶 day13stream流和方法引用

1.不可变集合 1.1 什么是不可变集合 ​ 是一个长度不可变&#xff0c;内容也无法修改的集合 1.2 使用场景 ​ 如果某个数据不能被修改&#xff0c;把它防御性地拷贝到不可变集合中是个很好的实践。 ​ 当集合对象被不可信的库调用时&#xff0c;不可变形式是安全的。 简单…

von Mises-Fisher Distribution (代码解析)

torch.distribution 中包含了很多概率分布的实现&#xff0c;本文首先通过均匀分布来说明 Distribution 的具体用法, 然后再解释 von Mises-Fisher 分布的实现, 其公式推导见 von Mises-Fisher Distribution. 1. torch.distribution.Distribution 以下是 Uniform 的源码: cl…

黑灰产行业简介

参考&#xff1a;2021年黑灰产行业研究及趋势洞察报告 1. 有哪些场景面临大量黑灰产攻击&#xff1f; 1.营销活动场景 -- 该场景最为猖獗 1. 抹机及接码注册&#xff1a;黑灰产会使用抹机工具修改设备参数伪装成一台新设备&#xff0c;再配合联系卡商进行手机号接码&#xf…

面试(05)————Redis篇

目录 一、项目中哪些地方使用了redis 问题一&#xff1a;发生了缓存穿透该怎么解决&#xff1f; 方案一&#xff1a;缓存空数据 方案二&#xff1a;布隆过滤器 模拟面试 问题二&#xff1a; 发生了缓存击穿该怎么解决&#xff1f; 方案一&#xff1a;互斥锁 方案二&#xff…

vue3:树的默认勾选和全选、取消全选

实现的功能&#xff0c;上面有个选择框&#xff0c;当选中全部时&#xff0c;下方树被全选 代码&#xff1a; <template><div><el-select v-model"selectAll" style"margin-bottom: 10px;" change"handleSelectAllChange">&…

Vue2 —— 学习(九)

目录 一、全局事件总线 &#xff08;一&#xff09;全局总线介绍 关系图 对图中的中间商 x 的要求 1.所有组件都能看到 2.有 $on $off $emit &#xff08;二&#xff09;案例 发送方 student 接收方 二、消息订阅和发布 &#xff08;一&#xff09;介绍 &#xff08…

4.6 CORS 支持跨域

CORS (Cross-Origin Resource Sharing &#xff09;是由 W3C 制定的一种跨域资源共享技术标准&#xff0c;其目的就是为了解决前端的跨域请求。在 Java EE 开发中&#xff0c;最常见的前端跨域请求解决方案是 JSONP &#xff0c;但JSONP 只支持 GET 请求&#xff0c;这是 个很大…

数据结构之排序了如指掌(三)

目录 题外话 正题 快速排序 Hoare法 Hoare法思路 Hoare法代码详解 挖坑法 挖坑法思路 挖坑法代码 前后指针法 前后指针法思路 前后指针法代码 小结 题外话 我们接着把没有写完的排序内容完成,快速排序其实大同小异,大家好好把思路整理一下 正题 快速排序 快速排序一…

HarmonyOS 状态管理

在声明式 UI 框架中&#xff0c;数据的改变触发 UI 的重新渲染。在 ArkUI 中不是所有数据的变化都会触发 UI 重新渲染&#xff0c;只有 状态变量 才会引起 UI 重新渲染。 状态变量 状态变量&#xff1a; 指被状态装饰器装饰的变量&#xff0c;只有这种变量的改变才会引起 UI …

(2022级)成都工业学院数据库原理及应用实验七: 数据库安全

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、成品仅提供参考 3、如果成品不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 Navicat Premium 16 Mysql 8.0.36 实验要求 1、创建数据库hospital,在hospital数据库中创建科室表De…

第一个STM32F767IGT6核心板

一. 制作原因 起先是因为参加计算机设计大赛准备的板子&#xff0c;其作用是连接OV5640摄像头来识别车牌号&#xff0c;主要外设有摄像头&#xff0c;SDRAM&#xff0c;网口等。 二. 原理图和PCB 原理图 PCB 三. 测试 1. 测试SDRAM功能 按下按键我们可以在串口中看到内存…

LTspice/Simplis仿真代码使用

LTspice/Simplis仿真代码使用 HI uu们 HI uu们,关注我的uu经常看到我上面贴了很多仿真代码,但是不知道怎么用. 今天来介绍下仿真代码怎么用, 比如说,我们用OP07做了一个跟随器,如图1所示. 图1:OP07跟随器 他的仿真代码非常简单,如下所示 XU1 N002 vout N001 N003 vout LT…

【Linux】详解进程通信中信号量的本质同步和互斥的概念临界资源和临界区的概念

一、同步和互斥的概念 1.1、同步 访问资源在安全的前提下&#xff0c;具有一定的顺序性&#xff0c;就叫做同步。在多道程序系统中&#xff0c;由于资源有限&#xff0c;进程或线程之间可能产生冲突。同步机制就是为了解决这些冲突&#xff0c;保证进程或线程之间能够按照既定…

都以为他是自杀20年后遗书曝光才明白张国荣的离世不简单

在时光的长河中&#xff0c;有些瞬间如同流星划过天际&#xff0c;短暂却又璀璨夺目。二十年前的那个春天&#xff0c;一个灵魂从这个喧嚣世界悄然离去&#xff0c;留下无尽的叹息与疑问。他就是张国荣——一位被誉为“风华绝代”的巨星。许多人曾认定他的离开是一场悲剧性的自…

计算机网络 -- 多人聊天室

一 程序介绍和核心功能 这是基于 UDP 协议实现的一个网络程序&#xff0c;主要功能是 构建一个多人聊天室&#xff0c;当某个用户发送消息时&#xff0c;其他用户可以立即收到&#xff0c;形成一个群聊。 这个程序由一台服务器和n个客户端组成&#xff0c;服务器扮演了一个接受…

element-ui合计逻辑踩坑

element-ui合计逻辑踩坑 1.快速实现一个合计 ​ Element UI所提供的el-table中提供了方便快捷的合计逻辑实现&#xff1a; ​ https://element.eleme.cn/#/zh-CN/component/table ​ 此实现方法在官方文档中介绍详细&#xff0c;此处不多赘述。 ​ 这里需要注意&#xff0c…

Don‘t fly solo! 量化之路,AI伴飞

在投资界&#xff0c;巴菲特与查理.芒格的神仙友谊&#xff0c;是他们财富神话之外的另一段传奇。巴菲特曾这样评价芒格&#xff1a;他用思想的力量拓展了我的视野&#xff0c;让我以火箭的速度&#xff0c;从猩猩进化到人类。 人生何幸能得到一知己。如果没有这样的机缘&…

每日学习笔记:C++ STL算法之容器元素变序

目录 反转元素次序 reverse(beg, end) reverse_copy(srcBeg, srcEnd, destEnd) 旋转元素 旋转&#xff1a;rotate(beg, newBeg, end) 复制同时旋转&#xff1a;rotate_copy(srcBeg, srcNewBeg, srcEnd, destBeg) 对元素做排列组合情况列举与切换 next_permutation(beg, …