PHP 于小项目:从鉴权说起

PHP 于小项目:从鉴权说起

在当今这个开发技术多样化的时代,选择合适的开发语言和框架常常决定了项目的效率与成败。对于个人开发者,特别是那些进行小型、短期项目的人来说,PHP 是一种特别友好的选择。本文将通过介绍 PHP 实现鉴权(登录)的方式,探讨为何它如此适合个人开发者的临时小项目。

为什么选择 PHP?

1. 易于部署:即开即用

PHP 的核心优势之一便是它极其简单的部署方式。你几乎可以在任何支持 HTTP 的服务器上运行 PHP,无需复杂的配置。对于那些快速验证想法或开发小型项目的个人开发者来说,这意味着你可以省去繁琐的设置工作,把精力更多地放在功能实现上。

试想一下,你想要快速上线一个简单的网站或工具,选择 PHP 意味着你不必去学习额外的工具链,也不必安装复杂的运行环境。将 PHP 文件放在服务器上即可运行,真是再轻便不过了。

2. 资源占用小:应对低访问量的理想选择

相比于许多其他后端语言,PHP 对于少量并发请求的处理效率非常高,这使得它在资源占用方面表现优异。当你进行一个小型项目,用户数量少或者访问量不高时,PHP 几乎不占用多少系统资源,而你不必担心它的性能瓶颈。

在这个场景下,PHP 就像是一辆小型的燃油车,而其他语言如 Node.js、Java 等则可能是高速跑车。虽然跑车在赛道上速度更快,但日常使用、资源有限的情况下,小车反而更适合,性价比更高。


鉴权(登录)的常见实现

让我们通过鉴权功能来进一步说明 PHP 的便利性。鉴权是任何涉及用户系统的项目中必不可少的部分,而 PHP 提供了简单高效的工具来实现这一功能。

鉴权流程概览

  1. 用户访问登录页面:用户通过表单输入用户名和密码。
  2. 验证用户信息:系统接受用户输入的信息,并在数据库中查找对应的记录。通过对比数据库中的散列密码与用户输入的密码,确认用户身份。
  3. 生成会话:一旦身份验证成功,系统为用户生成一个唯一的会话 ID(session),并将该会话保存在服务器端。
  4. 跳转至用户主页:最后,用户被重定向到受保护的用户主页,可以进行相应的操作。

PHP 实现登录鉴权示例

以下是使用 PHP 实现的一个简单的登录鉴权示例:

<?php
// 启动会话
session_start();// 连接数据库
$conn = new mysqli("localhost", "username", "password", "database");// 检查是否存在提交的用户名和密码
if ($_SERVER["REQUEST_METHOD"] == "POST") {$username = $_POST['username'];$password = $_POST['password'];// 查询用户信息$sql = "SELECT id, password_hash FROM users WHERE username = ?";$stmt = $conn->prepare($sql);$stmt->bind_param("s", $username);$stmt->execute();$stmt->bind_result($id, $password_hash);// 检查用户是否存在以及密码是否匹配if ($stmt->fetch() && password_verify($password, $password_hash)) {// 密码验证成功,设置会话$_SESSION['user_id'] = $id;header("Location: homepage.php"); // 跳转到主页} else {echo "用户名或密码错误";}$stmt->close();
}
?>
解释:
  • 会话管理:通过 session_start(),我们启动了一个会话机制。登录成功后,用户的会话信息会存储在服务器上,而客户端只需保存会话 ID。
  • 密码散列验证:在用户注册时,将密码经过 password_hash() 处理为不可逆的散列值。在登录时,通过 password_verify() 来检查用户输入的密码是否与散列值相匹配。
  • 安全性:密码并非明文存储,散列算法确保即使数据库泄露,攻击者也无法直接获取用户的原始密码。

客户端通常只持有一个 session_id,这个 ID 是服务端和客户端沟通用户会话状态的桥梁。下面我们就深入讲讲 服务端的 session 存储与管理 机制。

1. 什么是 Session?

Session 是一种基于服务器端的会话管理机制,目的是在无状态的 HTTP 请求中保持用户的状态信息。在每次 HTTP 请求中,客户端都会将 session_id 发送给服务器,服务器根据这个 session_id 找到与之对应的用户数据。

打个比方,session_id 就像你去咖啡馆消费时领取的号码牌。每次你去柜台点单,店员都通过你的号码牌确认你的订单信息。而服务端的 session 存储就像是后台存放着的每个顾客的订单数据。

2. Session 的工作流程

  1. 初次请求:当用户首次访问服务器时,客户端还没有会话标识(session_id),服务器会为用户创建一个新的会话,并生成一个唯一的 session_id
  2. **服务器返回 ****session_id**:服务器将这个 session_id 通过 HTTP 响应的 Set-Cookie 头部返回给客户端,客户端将其保存在浏览器的 cookie 中。
  3. 后续请求:客户端在后续请求中,浏览器会自动将这个 session_id 作为 cookie 的一部分发送给服务器。
  4. 服务器查找会话:服务器根据收到的 session_id 查找保存在服务端的 session 数据。
  5. 响应数据:服务器根据会话信息返回相应的用户数据。

3. 服务端 Session 的存储与管理

3.1 默认情况下的文件存储

在 PHP 中,session 的默认存储方式是文件系统。也就是说,服务端会将每个用户的 session 数据存储在服务器的文件系统中。具体来说,当客户端请求生成 session_id 后,服务器会在一个特定的目录下创建一个以该 session_id 为文件名的文件,并将用户的相关信息(如用户 ID、登录状态等)保存到这个文件中。

默认的 session 存储路径通常可以在 PHP 配置文件 php.ini 中找到:

session.save_path = "/var/lib/php/sessions"

每个 session 文件看起来大致如下:

sess_abcd1234efgh5678ijkl9012mnop3456

文件内容可能是一些序列化的 PHP 数据结构,比如:

username|s:8:"JohnDoe";login_time|i:1609459200;

3.2 使用数据库存储

对于大部分生产环境,尤其是需要处理大量并发的场景,文件存储可能会变得不够高效。这时,开发者可以选择将 session 数据存储在数据库中,常见的数据库包括 MySQL、Redis、Memcached 等。使用数据库存储可以更方便地实现数据的持久化、集中化管理和扩展。

  • MySQL 存储:你可以在 php.ini 中配置 PHP 将 session 存储到 MySQL 数据库中,每次请求根据 session_id 查找数据库中对应的记录。 数据表结构类似如下:
CREATE TABLE sessions (session_id VARCHAR(255) PRIMARY KEY,session_data TEXT,last_updated TIMESTAMP
);
  • Redis 或 Memcached:使用 Redis 或 Memcached 等内存数据库存储 session,可以显著提高查询速度,因为数据都存储在内存中。这个方案通常用于大并发、高性能的场景。

3.3 自定义 Session 处理器

PHP 提供了一种灵活的方式,允许开发者自定义 session 存储方式,借助 session_set_save_handler() 函数,开发者可以自己定义存储、读取、更新、销毁 session 的方法。

那么,在php 中,Session 是如何被管理的?我们又能对session进行哪些服务端的设置呢?

Session 的基础管理

在 PHP 中,Session 的管理相当简单,主要通过 session_start() 开启或恢复会话,数据的存储和读取则通过超全局变量 $_SESSION 进行。

基本操作

// 启动或恢复 session
session_start();// 存储数据到 session 中
$_SESSION['key'] = 'value';// 读取 session 数据
$value = $_SESSION['key'];// 删除特定的 session 数据
unset($_SESSION['key']);// 销毁整个 session
session_destroy();

解释:

  • session_start():启动或恢复现有会话。在每个需要使用 session 的页面上,必须首先调用该函数。
  • $_SESSION:超全局数组,用来存储用户的会话数据。所有与该用户相关的数据都可以存储在这个数组中。
  • unset():删除某个特定会话变量。如果要删除所有数据但不销毁会话,可以使用 $_SESSION = array();
  • session_destroy():销毁当前会话,包括删除服务器端存储的会话数据,但不会删除客户端保存的 session_id

Session 的生命周期

Session 生命周期决定了会话数据在服务器端的有效期。PHP 通过设置 session.gc_maxlifetimesession_set_cookie_params 来控制会话的存续时间。

设置会话有效期为 1 小时的示例:

// 设置 session 有效期为1小时(3600秒)
ini_set('session.gc_maxlifetime', 3600);// 设置 cookie 的有效期
session_set_cookie_params(3600);// 启动 session
session_start();

解释:

  • session.gc_maxlifetime:控制 session 数据的存活时间,单位为秒。即在用户不访问的情况下,Session 数据在服务器上保存的时间。
  • session_set_cookie_params():控制客户端 cookie 的生命周期。它决定了浏览器何时清除客户端的 session_id

通过这两个参数,你可以灵活地控制用户的会话存续时间,确保会话的安全性和用户体验。

安全考虑

Session 是非常安全和高效的会话管理方式,但如果不采取额外的安全措施,仍可能面临一些常见攻击。以下是几种常见的安全问题及其防范措施。

1. 防止 Session 劫持

Session 劫持是指攻击者通过拦截网络流量,获取用户的 session_id,从而伪装成合法用户进行操作。为了防止这种情况,我们可以采取以下措施:

  • 使用 HTTPS:通过 HTTPS 加密传输,确保 session_id 不会被中间人攻击截获。

2. 防止 Session 固定攻击

Session 固定攻击是指攻击者在用户登录前,向用户预设一个已知的 session_id,然后在用户登录后利用该会话。这种攻击通过固定会话 ID 来冒充用户。

  • 重新生成 session ID:在用户登录成功后,强制生成新的 session_id,从而防止旧的 session_id 被攻击者利用。
// 登录成功后,重新生成 session ID
session_regenerate_id(true);

session_regenerate_id(true) 可以确保在登录后生成一个新的 session ID,并销毁旧的 session 数据,有效防止 session 固定攻击。

3. 敏感数据加密

在某些情况下,你可能会在 Session 中存储敏感信息,如用户的个人身份信息或认证凭据。为确保这些数据的安全性,建议对其进行加密处理。

// 使用加密函数对敏感数据进行加密存储
$_SESSION['sensitive_data'] = encrypt($sensitive_data);

加密与解密功能可以根据你的应用需求自行定义,但一定要保证加密算法的强度和安全性。

完整的 Session 管理示例

下面我们通过一个完整的例子,展示如何在用户登录成功后,管理和使用 PHP 的 Session,同时考虑安全性问题。

<?php
// 启动 session
session_start();// 假设用户登录成功
$login_successful = true;
$user_id = 12345;
$username = 'JohnDoe';
$sensitive_data = 'ThisIsSensitiveData';if ($login_successful) {// 防止 session 固定攻击:重新生成 session IDsession_regenerate_id(true);// 存储用户数据到 session$_SESSION['user_id'] = $user_id;$_SESSION['username'] = $username;$_SESSION['login_time'] = time();// 加密并存储敏感数据$_SESSION['sensitive_data'] = encrypt($sensitive_data);
}// 读取 session 数据
if (isset($_SESSION['user_id'])) {echo "欢迎回来, " . $_SESSION['username'] . "<br>";echo "您的上次登录时间是: " . date('Y-m-d H:i:s', $_SESSION['login_time']) . "<br>";
}// 注销时,销毁 session
if ($logout) {session_destroy();echo "您已成功登出。";
}
?>

代码说明:

  1. 重新生成 session ID:登录成功后,我们通过 session_regenerate_id(true) 生成一个新的会话 ID,从而防止 session 固定攻击。
  2. 加密敏感数据:将用户的敏感数据加密后存储在 session 中,避免明文暴露可能带来的风险。
  3. 销毁 session:当用户选择注销时,调用 session_destroy() 彻底销毁会话。

服务端Session 生命周期配置

PHP 的 session 并不会永久保存,服务器会根据配置文件中的设置定期清理过期的 session 数据。这些配置通常可以在 php.ini 中找到,例如:

session.gc_maxlifetime = 1440   ; session 数据的有效时间(秒)
session.gc_probability = 1      ; 垃圾回收器的触发概率
session.gc_divisor = 1000       ; 垃圾回收器概率的分母

在上面的设置中,每次有 1/1000 的概率触发垃圾回收机制,删除超过 1440 秒(24 分钟)没有访问过的 session。

总结

  • **客户端只存储 ****session_id**:这只是一个唯一标识,真正的用户数据都存储在服务器端。
  • 服务端通过文件或数据库管理 session 数据:PHP 默认将 session 存储在文件系统中,但在高并发场景中,开发者可以选择数据库或内存数据库(如 Redis)来存储 session。
  • 灵活性与安全性:PHP 提供了高度灵活的自定义 session 存储方案,确保你可以根据项目需求调整会话管理方式,同时通过散列密码、 HTTPS 等方式保障安全性。

对于小型个人项目,PHP 默认的文件 session 存储已足够轻量且高效。而对于复杂项目,自定义 session 存储可以让你在性能和扩展性上实现更好的平衡。


是否要试试php?

PHP 由于其简单易用资源占用低高效的会话管理,非常适合个人开发者的小型项目。特别是在实现登录鉴权时,PHP 提供了极其简便的工具,帮助开发者快速完成用户验证的流程。

对于那些不需要处理大规模并发请求、只需简单鉴权功能的小项目来说,PHP 无疑是最佳选择之一。正如我们常说的,选择合适的工具远比选择最热门的工具更重要。在某些特定场景下,PHP 这种“经典的燃油车”可能会比“电动超跑”更符合需求。

如果你是一名个人开发者,正打算启动一个小项目,不妨试试 PHP。或许你会惊讶于它的简便和高效。

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

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

相关文章

Acwing 最小生成树

最小生成树 最小生成树:由n个节点&#xff0c;和n-1条边构成的无向图被称为G的一棵生成树&#xff0c;在G的所有生成树中&#xff0c;边的权值之和最小的生成树&#xff0c;被称为G的最小生成树。&#xff08;换句话说就是用最小的代价把n个点都连起来&#xff09; Prim 算法…

shell 脚本练习

一、初识shell 文件描述符与重定向 0&#xff1a;标准输入 1&#xff1a;标准正确输出 2&#xff1a;标准错误输出 1>a.txt 与 >a.txt 一样&#xff0c;不写默认前面为1&#xff0c;省略&#xff0c;把标准输出重定向到a.txt中 2>a.txt 将错误输出重定向到a.txt中 &a…

在 CentOS 安装 Python3.7 (没有弯路)

下载Python源码包 wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz安装前准备 安装依赖组件 yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel xz-devel解压安装 解…

【Redis】渐进式遍历 数据库管理命令 RESP协议

目录 渐进式遍历 scan 数据库管理命令 切换数据库 获取当前数据库key的个数 删除当前数据库所有的key 删除所有数据库中所有的key RESP协议 渐进式遍历 Redis使用scan命令进行渐进式遍历键&#xff0c;进而解决直接使用keys获取键时可能出现的阻塞问题&#xff08;因为…

ctf.show---->r3

做题笔记。 下载 查壳。 64ida打开。 先运行一下&#xff1a; &#xff1f; 不是说4位数值么。。。 得&#xff0c;看ida。 __isoc99_sscanf(dest, "%x", &v5); 懂了 dest指向的是v5 ,那么dest怎么来的&#xff1a; 往上走&#xff1a; 通过strncpy得到 但是问题…

Arthas redefine(加载外部的.class文件,redefine到JVM里 )

文章目录 二、命令列表2.2 class/classloader相关命令2.2.3 redefine&#xff08;加载外部的.class文件&#xff0c;redefine到JVM里 &#xff09;举例1&#xff1a;加载新的代码&#xff0c;jad/mc 命令使用举例2&#xff1a;上传 .class 文件到服务器的技巧 二、命令列表 2.…

WEB服务器——Tomcat

服务器是可以使用java完成编写&#xff0c;是可以接受页面发送的请求和响应数据给前端浏览器的&#xff0c;而在开发中真正用到的Web服务器&#xff0c;我们不会自己写的&#xff0c;都是使用目前比较流行的web服务器。 如&#xff1a;Tomcat 1. 简介 Tomcat 是一个开源的轻量…

汽车总线之---- LIN总线

Introduction LIN总线的简介&#xff0c;对于传统的这种点对点的连接方式&#xff0c;我们可以看到ECU相关的传感器和执行器是直接连接到ECU的&#xff0c;当传感器和执行器的数量较少时&#xff0c;这样的连接方式是能满足要求的&#xff0c;但是随着汽车电控功能数量的不断增…

Vue下载静态文件

1、需求&#xff1a;将静态文件放在本地&#xff0c;让用户进行下载。 2、文件位置&#xff1a; ① 原生js&#xff1a;直接将文件放在某个目录或者根目录下 ② Vue&#xff1a;将文件放在根目录的public文件夹下面 3、代码示例&#xff1a; const url "/模板.xlsx"…

Halcon实用系列1-识别二维条码

在做项目时&#xff0c;之前使用的是某康的智能读码器&#xff0c;综合考虑成本&#xff0c;可通过相机拍照来读取图片的二维码&#xff0c;我这边用Halcon来实现。 Halcon代码如下&#xff1a; *创建模型 create_data_code_2d_model(Data Matrix ECC 200, [], [], DataCodeH…

linux蓝屏重启解决方法汇总

前言 linux系统蓝屏&#xff08;Blue Screen Of Death&#xff09;是Linux系统用户遇到最严重的故障&#xff0c;任何新手都无法直接解决它。在遇到蓝屏时&#xff0c;最好的解决方案是联系Linux专业供应商或Linux专业支持工程师&#xff0c;因为他们有系统的协议和经验来解决…

dockerfile部署springboot项目(构建镜像:ebuy-docker:v1.0)

文章目录 1、docker部署Mysql2、dockerfile构建镜像1.1、在idea中导入课件中的项目资料\day01\ebuy-docker1.2、修改项目application.yml数据库连接参数1.3、启动项目访问测试&#xff1a;http://localhost:8081/1.4、执行mvn package命令进行项目打包1.5、虚拟机中新建目录/op…

SpringBoot(Java)实现MQTT连接(本地Mosquitto)通讯调试

1.工作及使用背景 工作中需要跟收集各种硬件或传感器数据用于Web展示及统计计算分析&#xff0c;如电表、流量计、泵、控制器等物联网设备。 目前的思路及解决策略是使用力控或者杰控等组态软件实现数据的转储&#xff08;也会涉及收费问题&#xff09;&#xff0c;通过组态软件…

NDI多画面系统(Multiview Pro)

NDI多画面系统(Multiview Pro)是千视以Multiview Player为基础打造的一款全新的多画面监看切换系统,支持自定义多画面/多窗口显示,单窗口可监看20路视频流,可实现多窗口、多屏幕预监+切换,且兼容NDI High Bandwidth和NDI HX/NDI HX3。同时Multiview Pro基于WebRTC技术,可…

用 Git Absorb 轻松管理 commit,告别频繁 fixup,效率提升 10 倍!

你是不是经常在使用 Git 的时候被频繁的 commit --fixup 弄得头疼?尤其是在修复代码时,一个小改动就得新建一个 commit,搞得整个 commit 历史乱七八糟,不仅影响工作效率,后来要查找问题时也变得更复杂。如果你对这个问题深有感触,那么这篇文章就是为你写的。 今天我想…

JVM 类加载机制2

扩展类加载器&#xff08;Extension ClassLoader&#xff09;&#xff0c;该类加载器是由 ExtClassLoader&#xff08;sun.misc.Launcher$ExtClassLoader&#xff09;实现&#xff0c;负责将 <JRE_HOME>/lib/ext 或者被 java.ext.dir 系统变量所指定路径中的所有类库加载…

open-resty 服务安装kafka插件

从github下载 作者&#xff1a;程序那点事儿 日期&#xff1a;2023/11/16 22:01 lua-resty-kafka 插件安装 下载代码后直接解压 mkdir -p /usr/local/openresty/modules/ #创建一个目录&#xff0c;存放lua插件cd /usr/local/openresty/modules/ #进入目录rz -y #上传lua插件…

SOMEIP_ETS_136: SD_Option_Length_shorter_GT_0_as_specified_for_type

测试目的&#xff1a; 验证DUT能够处理一个UDP选项长度小于其类型所指定长度的SubscribeEventgroup消息&#xff0c;并以SubscribeEventgroupNAck作为响应或完全忽略该请求。 描述 本测试用例旨在确保DUT遵循SOME/IP协议&#xff0c;当接收到一个UDP选项长度小于其类型所指定…

WPS在表格中填写材料时,内容过多导致表格不换页,其余内容无法正常显示 以及 内容过多,导致表格换页——解决方法

一、现象 1&#xff0c;内容过多导致表格不换页&#xff0c;其余内容无法正常显示 2&#xff0c;内容过多&#xff0c;导致表格换页 二、解决方法 在表格内右击&#xff0c;选择表格属性 在菜单栏选择行&#xff0c;勾选允许跨页断行&#xff0c;点击确定即可 1&#xff0…

windows安装Redis以后配置远程访问

修改配置文件&#xff1a; 第一个地方&#xff1a; 第二个地方&#xff1a; 启动服务&#xff1a; redis-server .\redis.windows.conf 可能需要重启计算机 经过实测&#xff0c;这个配置文件也得改&#xff1a; 如果不想重启计算机&#xff0c;可以执行下面的命令重启…