当前位置: 首页 > news >正文

身份鉴权(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中所常用的身份鉴权技术介绍完毕,累死我了~

相关文章:

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

免责声明&#xff1a;本文章仅用于交流学习&#xff0c;因文章内容而产生的任何违法&未授权行为&#xff0c;与文章作者无关&#xff01;&#xff01;&#xff01; 附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;…...

【git】-初始git

一、什么是版本控制&#xff1f; 二、Git的安装 三、掌握Linux常用命令 四、Git基本操作 1、提交代码 2、查看历史提交 3、版本回退 一、什么是版本控制&#xff1f; 版本控制是一种用于记录文件或项目内容变化的系统。它通过版本标识和版本历史记录来管理不同版本&#…...

CSS 盒模型

盒模型 CSS盒模型是网页布局的核心概念之一&#xff0c;它描述了网页元素的物理结构和元素内容与周围元素之间的关系。根据W3C规范&#xff0c;每个HTML元素都被视为一个矩形盒子&#xff0c;这个盒子由以下四个部分组成&#xff1a; 内容区&#xff08;Content area&#xff…...

[0405].第05节:搭建Redis主从架构

Redis学习大纲 一、3主3从的集群配置&#xff1a; 1.1.集群规划 1.分片集群需要的节点数量较多&#xff0c;这里我们搭建一个最小的分片集群&#xff0c;包含3个master节点&#xff0c;每个master包含一个slave节点&#xff0c;结构如下&#xff1a; 2.每组是一主一从&#x…...

6 分布式限流框架

限流的作用 在API对外互联网开放的情况下&#xff0c;是无法控制调用方的行为的。当遇到请求激增或者黑客攻击的情况下&#xff0c;会导致接口占用大量的服务器资源&#xff0c;使得接口响应效率的降低或者超时&#xff0c;更或者导致服务器宕机。 限流是指对应用服务进行限制…...

sosadmin相关命令

sosadmin命令 以下是本人翻译的官方文档&#xff0c;如有不对&#xff0c;还请指出&#xff0c;引用请标明出处。 原本有个对应表可以跳转的&#xff0c;但是CSDN的这个[](#)跳转好像不太一样&#xff0c;必须得用html标签&#xff0c;就懒得改了。 sosadmin help 用法 sosadm…...

关于大数据的基础知识(四)——大数据的意义与趋势

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于大数据的基础知识&#xff08;四&a…...

【EI,Scopus检索 | 往届均已检索见刊】第四届智能系统、通信与计算机网络国际学术会议(ISCCN 2025)

重要信息&#xff1a; 大会官网&#xff1a;更多详情【论文投稿】 截稿时间&#xff1a;以官网信息为准 大会时间&#xff1a;2025年2月21-23日 接受/拒稿通知&#xff1a;投稿后3-5个工作日内 收录检索&#xff1a;EI&#xff0c;Scopus 出版信息&#xff1a; 本会议所有…...

smplx blender插件笔记

目录 liunx安装&#xff1a; liunx安装&#xff1a; pip install smplx 这个创建模型报错 SMPL_blender_addon...

【算法】移除元素

今天讲的是力扣题目的题解&#xff1a; 力扣题目&#xff1a; 72.移除元素 题目描述&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不…...

【后端面试总结】设计一个分布式锁需要考虑哪些东西

分布式锁是我们在分布式场景中经常用到的一种技术&#xff0c;在后端面试中也是出镜率很高&#xff0c;那么我们设计分布式锁的时候应该从那几方面去考虑呢 实现分布式锁需要考虑的点 设置超时时间 设置超时时间的目的是为了避免这个场景&#xff1a;进程A拿了锁&#xff0c…...

awr报告无法生成:常见案例与解决办法

awr报告无法生成:常见案例与解决办法 STATISTICS_LEVEL设置过低数据库打开状态不对主库隐含参数设置错误MMON子进程被SuspendSYS模式统计信息过期WRH$_SQL_PLAN表数据量太大AWR绑定变量信息收集超时撞上数据库Bug 9040676STATISTICS_LEVEL设置过低 STATISTICS_LEVEL设置为BAS…...

Hadoop 生态之 kerberos

参考链接 https://winway.github.io/2022/04/02/kerberos-ranger/ https://ieevee.com/tech/2016/06/22/ranger-2.html kerberos解决”who are you“的问题 ranger解决”what you can do“的问题 LDAP 轻型目录访问协议&#xff08;英文&#xff1a;Lightweight Director…...

【文件I/O】文件持久化

这篇文章详细讲解的是 理解在Linux操作系统中输入/输出&#xff08;I/O&#xff09;编程与文件操作的关系。 在计算机编程中&#xff0c;输入/输出编程&#xff08;I/O 编程&#xff09; 是一个重要的概念&#xff0c;指的是通过程序与外部世界&#xff08;如用户输入、文件、…...

USB学习——基本概念

文章目录 USB&#xff08;Universal Serial Bus&#xff09;概述USB系统的描述USB总线传输方式USB的拓扑结构 USB的连接模型USB控制器及分类USB描述符USB 端点USB枚举过程USB 四种传输类型USB 事务批量传输(Bulk)中断传输(Interrupt)等时传输(Isochronous)控制传输(Control)端点…...

python-leetcode-三数之和

15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums.sort() # 排序n len(nums)res []for i in range(n):# 剪枝&#xff1a;如果当前数 > 0&#xff0c;三数之和不可能为 0if nums[i]…...

springboot整合拦截器

1.首先创建拦截器类&#xff1a; package com.example.interceptor;import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.sp…...

B树与B+树:数据库索引的秘密武器

想象一下&#xff0c;你正在构建一个超级大的图书馆&#xff0c;里面摆满了各种各样的书籍。B树和B树就像是两种不同的图书分类和摆放方式&#xff0c;它们都能帮助你快速找到想要的书籍&#xff0c;但各有特点。 B树就像是一个传统的图书馆摆放方式&#xff1a; 1. 书籍摆放&…...

Lua语言中常用的字符串操作函数

string.sub(s, i, j) 功能: 截取字符串 s 中从位置 i 到位置 j 的子字符串。 local s "Hello, Lua!" print(string.sub(s, 1, 5)) -- 输出 "Hello" print(string.sub(s, 8, 11)) -- 输出 "Lua!" string.len(s) 功能&#xff1a;将字符串长度…...

HOW - Form 表单确认校验两种模式(以 Modal 场景为例)

目录 一、背景二、具体1. 模式一&#xff1a;点击确认进行校验提示2. 模式二&#xff1a;确认按钮依赖于表单内容实现说明 一、背景 基于react、antd form分别实现如下两种模式&#xff1a; 1、一个 Modal&#xff0c;点击确认进行校验提示2、一个 Modal&#xff0c;确认按钮…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...