PHP Session 会话管理与安全配置
时间:2026-11-15 07:15 作者:emer 分类: 无
PHP Session 会话管理与安全配置
一、Session 解决什么问题
HTTP 是无状态协议,服务器分不清两次请求是不是同一个用户。Session 把用户数据保存在服务器端,浏览器只存一个 Session ID(通常放在 Cookie 里),后续请求带上这个 ID,服务器据此找回用户状态。登录态、购物车、权限校验都依赖它。
二、基本用法
<?php
// 必须在任何输出之前调用
session_start();
$_SESSION['user_id'] = 1001;
$_SESSION['username'] = 'zhangsan';
// 读取
echo $_SESSION['username'] ?? '未登录';
// 销毁单个或全部
unset($_SESSION['user_id']);
session_destroy(); // 清空整个会话
session_start() 必须放在脚本最前面,任何 echo、空格输出之前,否则会报 headers already sent。
三、工作原理
- 首次访问,PHP 生成唯一 Session ID,通过 Set-Cookie 下发给浏览器;
- 浏览器后续请求自动携带 PHPSESSID;
- 服务器根据 ID 读取对应会话文件(默认在 /tmp);
- 请求结束把改动写回。Session 数据存在服务端,比直接把信息放 Cookie 安全。
四、关键安全配置(php.ini)
session.cookie_httponly = On
session.cookie_secure = On
session.cookie_samesite = Strict
session.use_strict_mode = On
session.gc_maxlifetime = 1440
httponly:Cookie 禁止 JS 读取,防 XSS 窃取;secure:只在 HTTPS 下传 Cookie;samesite=Strict:阻止跨站请求携带 Cookie,缓解 CSRF;use_strict_mode:拒绝客户端伪造的、服务器不存在的 Session ID;gc_maxlifetime:会话过期时间,单位秒。
五、登录后必须重新生成 ID
登录成功时调用 session_regenerate_id(true) 换新 ID,防止会话固定攻击:
if ($loginOk) {
session_regenerate_id(true); // true 删除旧会话
$_SESSION['user_id'] = $user['id'];
}
六、常见误区
- 把敏感密码明文存 Session,应只存用户 ID,密码永不入库也不入会话;
- 退出登录只清 Cookie 不调 session_destroy,服务端旧会话仍在;
- 多台服务器共用默认文件会话,换机器登录态丢失,需改用 Redis 或数据库存储;
- 关闭浏览器就以为会话消失,其实服务端文件还在,靠 gc 回收;
- 跨域、子域名使用时忘配 cookie_domain,导致会话读不到。
七、分布式存储方案
高并发多实例场景,把 Session 存 Redis:
// php.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
所有实例共享同一会话,配合过期策略自动清理。
八、总结
Session 靠服务器存数据、Cookie 存 ID 维持登录态。安全要点:开启 httponly/secure/samesite、登录后重生成 ID、退出彻底销毁、分布式用 Redis 共享。理解无状态协议与会话绑定机制,才能避免 XSS、CSRF、会话固定等常见风险。