身份鉴权(PHP)(小迪网络安全笔记~

免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!!
附:完整笔记目录~
ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!

1.2 🐘身份鉴权(PHP)

  1. 引子:上一章主要对PHP中全局变量做了介绍,其中$_COOKIE$_SESSION常常在身份鉴权中被使用。而本章则是由代码具体聊聊在PHP Web中开发者所常使用的身份鉴权方式。
    这里再简单介绍一下身份鉴权,确认用户&系统在访问某受限资源时,身份是否合法。若想具体了解各鉴权方式的工作流程&优缺点,可参考:https://blog.csdn.net/qq_62040731/article/details/144435112

  2. Http基本鉴权
    由用户名&密码确认用户身份,是最基础但也最麻烦的鉴权方式,即用户每一次访问任意的受限资源前都需要输入用户名密码。接下来我们写一个本地demo。

    • 首先写一个登录框。

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录</title><link rel="stylesheet" href="styles.css">
      </head>
      <body><div class="login-container"><h2>后台登录</h2><form action="BasiccheckDemo1.php" method="POST"><div class="form-group"><label for="username">用户名</label><input type="text" id="username" name="username" required></div><div class="form-group"><label for="password">密码</label><input type="password" id="password" name="password" required></div><button type="submit" class="login-btn">登录</button></form></div><?phpif (isset($_GET['error'])){echo "<script>alert('用户名或密码错误!');</script>";echo "<script>// 使 URL 仅保留原路径而不携带任何参数history.replaceState(null, null, window.location.pathname);</script>";}?>
      </body>
      </html>
      
    • 其次再写一个登录框样式,使其美观一些,styles.css:

      body {font-family: Arial, sans-serif;background: linear-gradient(135deg, #ff9a9e, #fad0c4);display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;
      }
      .login-container {background-color: #ffffff;padding: 20px 30px;border-radius: 8px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);width: 100%;max-width: 400px;
      }
      .login-container h2 {margin: 0 0 20px;font-size: 24px;text-align: center;color: #333;
      }
      .form-group {margin-bottom: 15px;
      }
      .form-group label {display: block;margin-bottom: 5px;color: #555;
      }
      .form-group input {width: 100%;padding: 10px;border: 1px solid #ccc;border-radius: 4px;font-size: 14px;
      }
      .form-group input:focus {outline: none;border-color: #2575fc;box-shadow: 0 0 4px rgba(37, 117, 252, 0.5);
      }
      .login-btn {display: block;width: 100%;padding: 10px;background-color: #2575fc;border: none;border-radius: 4px;font-size: 16px;color: #fff;cursor: pointer;transition: background-color 0.3s ease;
      }
      .login-btn:hover {background-color: #1e63d9;
      }
      .login-container p {margin-top: 15px;text-align: center;font-size: 14px;
      }
      .login-container p a {color: #2575fc;text-decoration: none;
      }
      .login-container p a:hover {text-decoration: underline;
      }
      
    • 效果展示
      image-20250110125935671
      貌似也没那么美观哈哈~

    • 接下来再创建一个mysql数据库,库中存放着管理员的用户名&密码,用于后面的身份认证。

      -- 创建&使用数据库
      CREATE DATABASE IF NOT EXISTS authentication;
      USE authentication;-- 创建用户表
      CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(255) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      );-- 在表中插入数据
      INSERT INTO users (username, password) 
      VALUES 
      ('admin', 'sjjjer');
      
    • 写一个数据库配置文件,用于php与数据库间通信。

      <?php// 数据库配置
      $host = 'localhost'; // 数据库主机名
      $dbname = 'authentication'; // 数据库名
      $username = 'root'; // 数据库用户名
      $password = '123456'; // 数据库密码define('DB_HOST', $host);
      define('DB_NAME', $dbname);
      define('DB_USERNAME', $username);
      define('DB_PASSWORD', $password);
      
    • 再写身份认证逻辑。

      <?php
      // 引入数据库配置文件
      include 'db_config.php';// 连接数据库
      $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
      // 获取表单所提交的 username password
      $username = $_POST["username"];
      $password = $_POST["password"];
      // 判断获取到的 username password 是否在数据库中有所记录
      $sql = "SELECT * FROM users WHERE username = '$username' and password = '$password'";
      // 将查询结果存储至 $result 中
      $result = mysqli_query($conn, $sql);
      // 获取 $result 中的行数并判断,也就是 $sql 所获取结果的行数
      if (mysqli_num_rows($result) > 0) {header('Location: admin.php');exit();
      }else{header('Location: login.php?error=1');exit();
      }// 关闭数据库连接
      mysqli_close($conn);
      
    • 最后写一个后台页面。

      <?php
      echo "欢迎来到后台!";
      
    • 测试一下这段简单的demo
      image-20250110160305225

    由上述案例可知,只有当post所提交的用户名密码正确时,才会跳转至后台页面。可后台页面往往有很多,为了防止其他用户也能访问后台,难道要在每一个后台页面前都要加上判断用户名&密码是否正确的逻辑吗?于开发者&用户而言,很麻烦也没有必要,因此出现了Session-Cookie鉴权。

  3. Cookie鉴权
    当用户输入正确的用户名&密码时,服务端(一般情况下)会由所输入的用户名&密码生成Cookie,并将生成的Cookie返回给浏览器,浏览器收到Cookie并保存,当用户再次访问受限页面时会携带浏览器所保存的Cookie,而被访问页面仅需判断Cookie是否合法来实现身份鉴权,无需用户再次输入用户名&密码。

    • 基于Cookie的身份认证逻辑:

      <?php
      // 引入数据库配置文件
      include 'db_config.php';// 连接数据库
      $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);// 获取表单所提交的 username password
      $username = $_POST["username"];
      $password = $_POST["password"];// 判断获取到的 username password 是否在数据库中有所记录
      $sql = "SELECT * FROM users WHERE username = '$username' and password = '$password'";// 将查询结果存储至 $result 中
      $result = mysqli_query($conn, $sql);
      // 获取 $result 中的行数并判断,也就是 $sql 所获取结果的行数
      if (mysqli_num_rows($result) > 0) {setcookie("username", $username, time() + (86400), "/");setcookie("password", $password, time() + (86400), "/");header('Location: admin.php');exit();
      }else{header('Location: login.php?error=1');exit();
      }// 关闭数据库连接
      mysqli_close($conn);
      
    • 后台页面:

      <?php
      if ($_COOKIE['username'] == 'admin' and $_COOKIE['password'] == 'sjjjer') {echo "欢迎来到后台!";
      } else {header("location:login.php?error=1");
      }
      
    • ok,我们来测试一下这段demo:
      image-20250110193349610

    通过这段简单的demo实现了Cookie鉴权,但有没有发现什么问题呢?这段Cookie是由表单提交正确的username和password所生成的,一旦Cookie泄露,攻击者也就顺势得知了用户的用户名&密码。即使不由用户名&密码来生成Cookie,但由于Cookie的可读,攻击者也很容易伪造Cookie。
    综上,虽然Cookie解决掉了访问受限页面时身份鉴权的问题,但Cookie自身却仍存在安全问题,那有没有既实现身份鉴权又相对安全的做法呢? → Session-Cookie鉴权。

  4. Session-Cookie鉴权
    Session-Cookie的基本流程同Cookie,只不过由服务端返回给浏览器的并非所生成的Cookie值内容,而是Session ID,当浏览器下次请求受限页面时会携带其所存储的Session ID值。

    • 基于Session-Cookie的身份认证逻辑:

      <?php
      // 引入数据库配置文件
      include 'db_config.php';// 开启 session
      session_start();// 连接数据库
      $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);// 获取表单所提交的 username password
      $username = $_POST["username"];
      $password = $_POST["password"];// 判断获取到的 username password 是否在数据库中有所记录
      $sql = "SELECT * FROM users WHERE username = '$username' and password = '$password'";// 将查询结果存储至 $result 中
      $result = mysqli_query($conn, $sql);
      // 获取 $result 中的行数并判断,也就是 $sql 所获取结果的行数
      if (mysqli_num_rows($result) > 0) {$_SESSION['username'] = $username;$_SESSION['password'] = $password;header('Location: admin.php');exit();
      }else{header('Location: login.php?error=1');exit();
      }// 关闭数据库连接
      mysqli_close($conn);
      
    • 后台页面:

      <?php
      session_start();if ($_SESSION['username'] == 'admin' and $_SESSION['password'] == 'sjjjer') {echo "欢迎来到后台!";
      } else {header("location:login.php?error=1");
      }
      
    • 老样子,来测试一下该demo:
      image-20250110204530341

    由于Session ID的不可读&随机性,导致攻击者几乎不可能伪造。既解决了身份鉴权,又相较于Cookie更加安全。虽然无法伪造Session ID,但XSS、CSRF等窃取&利用Cookie的攻击仍然有效,即使不伪造身份,也仍有重放攻击(也就是爆破)的手段,直接获取用户名&密码。
    那么开发者针对重放攻击,有没有更好的应对手段呢? → 加Token。

  5. Token-Session鉴权
    用户在每一次登陆提交数据时会携带随机生成的Token,执行登录操作后会将携带的Token值刷新,若此时用户仍使用原Token提交登录数据则会被直接拒绝,避免了重放攻击。身份鉴权仍使用Session-Cookie,只是这里加了Token防爆破而已,所以这里的Token仅是一种防爆破的手段,而非一种新的鉴权方式。

    • 登录表单需要添加生成&提交Token的代码:

      <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录</title><link rel="stylesheet" href="styles.css">
      </head>
      <body><?php// 随机生成Token,并将其值存储至Session中session_start();$_SESSION['token'] = bin2hex(random_bytes(32));?><div class="login-container"><h2>后台登录</h2>
      <!--        <form action="BasiccheckDemo1.php" method="POST">-->
      <!--        <form action="CookiecheckDemo2.php" method="POST">-->
      <!--        <form action="SessioncheckDemo3.php" method="POST">--><form action="TokencheckDemo4.php" method="POST"><div class="form-group"><label for="username">用户名</label><input type="text" id="username" name="username" required></div><div class="form-group"><label for="password">密码</label><input type="password" id="password" name="password" required></div><button type="submit" class="login-btn">登录</button><!-- 隐藏字段用于提交Token --><input type="hidden" id="token" name="token" value="<?php echo $_SESSION['token']; ?>"></form></div><?phpif (isset($_GET['error'])){echo "<script>alert('用户名或密码错误!');</script>";echo "<script>// 使 URL 仅保留原路径而不携带任何参数history.replaceState(null, null, window.location.pathname);</script>";}?>
      </body>
      </html>
      
    • 在原有身份认证逻辑基础上,添加对Token的认证&刷新:

      <?php
      // 引入数据库配置文件
      include 'db_config.php';// 开启 session
      session_start();// 连接数据库
      $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);// 获取表单所提交的 username password token
      $username = $_POST["username"];
      $password = $_POST["password"];
      $token = $_POST["token"];// 判断获取到的 username password 是否在数据库中有所记录
      $sql = "SELECT * FROM users WHERE username = '$username' and password = '$password'";// 将查询结果存储至 $result 中
      $result = mysqli_query($conn, $sql);
      // 验证 token username password
      if (empty($token) || $token !== $_SESSION['token']) {echo "FBI, Don't Hack!!!";header('Location: login.php');
      } elseif (mysqli_num_rows($result) > 0) {$_SESSION['username'] = $username;$_SESSION['password'] = $password;header('Location: admin.php');exit();
      } else {$_SESSION['token'] = bin2hex(random_bytes(32));header('Location: login.php?error=1');exit();
      }// 关闭数据库连接
      mysqli_close($conn);
      
    • 后台页面同上。

    • 测试demo:
      image-20250110234340689

    至此!PHP中所常用的身份鉴权技术介绍完毕,累死我了~

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

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

相关文章

自定义音频播放样式结合Howler.js

滑动式滚动条 不使用audio默认样式 自定义音频播放样式 当前时间 开始时间 结束时间 可播放可暂停 滚动条可拖动进行同步 具体样式可调整npm install howler --save<template><div class"audio-player"><div v-if"isLoading" class"l…

LLM prompt提示构造案例:语音回复内容;o1思维链

1、语音回复内容 目的&#xff1a; 语音聊天助手的prompt&#xff0c;让大模型来引导聊天内容&#xff0c;简短和友好&#xff0c;从而文字转语音时候也比较高效。 ## 角色设定与交互规则 ### 基本角色 你是用户的好朋友. 你的回答将通过逼真的文字转语音技术阅读. ### 回答规则…

AES 与 SM4 加密算法:深度解析与对比

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

Sentinel服务保护 + Seata分布式事务

服务保护 【雪崩问题】微服务调用链路中某个服务&#xff0c;引起整个链路中所有微服务都不可用。 【原因】&#xff1a; 微服务相互调用&#xff0c;服务提供者出现故障。服务调用这没有做好异常处理&#xff0c;导致自身故障。调用链中所有服务级联失败&#xff0c;导致整个…

ssh2-sftp-client uploadDir Upload error: getLocalStatus: Bad path: ./public

报错解释 这个错误表明在使用 ssh2-sftp-client 这个Node.js库进行目录上传时遇到了问题。具体来说&#xff0c;是指定的本地路径&#xff08;./public&#xff09;不正确或者不存在。 解决方法&#xff1a; 确认当前工作目录&#xff1a;确保你在执行上传操作时的当前工作目…

AI赋能服装零售:商品计划智能化,化危机为转机

在服装零售这片竞争激烈的战场上&#xff0c;每一个细微的决策都可能成为品牌兴衰的关键。当市场波动、消费者口味变化、供应链挑战接踵而至时&#xff0c;许多品牌往往将危机归咎于外部环境。然而&#xff0c;真相往往更为深刻——“危机不是外部的&#xff0c;而是你的商品计…

基于YOLOv8的水下目标检测系统

基于YOLOv8的水下目标检测系统 (价格90) 使用的是DUO水下目标检测数据集 训练集 6671张 验证集 1111张 测试集 1111张 包含 [holothurian, echinus, scallop, starfish] [海参, 海胆, 扇贝, 海星] 4个类 通过PYQT构建UI界面&#xff0c;包含图片检测&#xff0c;视…

web-前端小实验4

实现以上图片中的内容 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用户注册</title&…

【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法)

【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型&#xff08;敏感性分析方法&#xff09; 引言 该文章实现了一个可解释的神经网络回归模型&#xff0c;使用BP神经网络&#xff08;BPNN&#xff09;来预测特征输出。该模型利用七个变量参数作为输入特征进行训练。为…

iOS 本地新项目上传git仓库,并使用sourceTree管理

此文记录的场景描述&#xff1a; iOS前期开发时&#xff0c;在本地创建项目&#xff0c;直至开发一段时间&#xff0c;初期编码及框架已完善后&#xff0c;才拿到git仓库的地址。此时需要将本地代码上传到git仓库。 上传至git仓库&#xff0c;可以使用终端&#xff0c;键入命令…

为深度学习引入张量

为深度学习引入张量 什么是张量&#xff1f; 神经网络中的输入、输出和转换都是使用张量表示的&#xff0c;因此&#xff0c;神经网络编程大量使用张量。 张量是神经网络使用的主要数据结构。 张量的概念是其他更具体概念的数学概括。让我们看看一些张量的具体实例。 张量…

欧拉公式和傅里叶变换

注&#xff1a;英文引文机翻&#xff0c;未校。 中文引文未整理去重&#xff0c;如有异常&#xff0c;请看原文。 Euler’s Formula and Fourier Transform Posted byczxttkl October 7, 2018 Euler’s formula states that e i x cos ⁡ x i sin ⁡ x e^{ix} \cos{x} i …

HDFS编程 - 使用HDFS Java API进行文件操作

文章目录 前言一、创建hdfs-demo项目1. 在idea上创建maven项目2. 导入hadoop相关依赖 二、常用 HDFS Java API1. 简介2. 获取文件系统实例3. 创建目录4. 创建文件4.1 创建文件并写入数据4.2 创建新空白文件 5. 查看文件内容6. 查看目录下的文件或目录信息6.1 查看指定目录下的文…

高德地图调用geoserver提供WMTS服务报错Unknown TILEMATRIX问题

1. 高德地图JSAPI要求WMTS必须是EPSG:3857坐标系 2. 高德调用WMTS服务时参数 TileMatrix中未带有坐标系字段&#xff0c;需要修改geoserver源码兼容一下&#xff0c;修改JSAPI也可以&#xff0c;如你用都用离线的话 leaflet加载geoserver的WMTS服务时TILEMATRIX字段 TILEMATR…

C语言——文件IO 【文件IO和标准IO区别,操作文件IO】open,write,read,dup2,access,stat

1.思维导图 2.练习 1&#xff1a;使用C语言编写一个简易的界面&#xff0c;界面如下 1&#xff1a;标准输出流 2&#xff1a;标准错误流 3&#xff1a;文件流 要求&#xff1a;按1的时候&#xff0c;通过printf输出数据&#xff0c;按2的时候&#xff0c;通过p…

C++实现图书管理系统(Qt C++ GUI界面版)

前瞻 本项目基于【C】图书管理系统(完整版) 图书管理系统功能概览&#xff1a; 登录&#xff0c;注册学生,老师借书&#xff0c;查看自己当前借书情况&#xff0c;还书。管理员增加书&#xff0c;查看当前借阅情况&#xff0c;查看当前所有借阅人&#xff0c;图书信息。 效果…

使用 NestJS 构建高效且模块化的 Node.js 应用程序,从安装到第一个 API 端点:一步一步指南

一、安装 NestJS 要开始构建一个基于 NestJS 的应用&#xff0c;首先需要安装一系列依赖包。以下是必要的安装命令&#xff1a; npm i --save nestjs/core nestjs/common rxjs reflect-metadata nestjs/platform-express npm install -g ts-node包名介绍nestjs/coreNestJS 框…

鸿蒙面试 2025-01-09

鸿蒙分布式理念&#xff1f;&#xff08;个人认为理解就好&#xff09; 鸿蒙操作系统的分布式理念主要体现在其独特的“流转”能力和相关的分布式操作上。在鸿蒙系统中&#xff0c;“流转”是指涉多端的分布式操作&#xff0c;它打破了设备之间的界限&#xff0c;实现了多设备…

Mysql--基础篇--SQL(DDL,DML,窗口函数,CET,视图,存储过程,触发器等)

SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于管理和操作关系型数据库的标准语言。它允许用户定义、查询、更新和管理数据库中的数据。SQL是一种声明性语言&#xff0c;用户只需要指定想要执行的操作&#xff0c;而不需要详细说明如何…

SQL 幂运算 — POW() and POWER()函数用法详解

POW() and POWER()函数用法详解 POW() 和 POWER() —计算幂运算&#xff08;即一个数的指定次方&#xff09;的函数。 这两个函数是等价的&#xff0c;功能完全相同&#xff0c;只是名字不同。 POW(base, exponent); POWER(base, exponent); base&#xff1a;底数。exponen…