xss学习3之服务端session
一、服务端的Session
1. cookie和session
1)cookie和session对比
- cookie: 保存在客户端,包含所有key-value信息,浏览器访问多个网站时会积累大量cookie,占用存储空间,并在每次请求时携带所有cookie,增加HTTP通信成本。
- session: 保存在服务端,只通过cookie字段给客户端下发一个session ID,简化了内容,减轻了客户端负担,提高了通信效率。
2)session创建、校验、销毁
- 创建: 用户第一次访问时开启会话,将登录信息保存到session,并通过cookie发送给客户端。如果勾选记住密码,则写入cookie。
- 校验: 用户后续访问时,发送session ID,服务端从session中取出信息,判断登录状态。
- 销毁: 用户注销时,销毁session,并使客户端cookie过期。
3)session创建、校验、销毁在PHP代码中的实现
- 用户登录界面
- 登录界面后端代码
- 开启会话: 调用session_start()产生session ID。
- 存储登录信息: 验证用户名和密码后,将用户名和登录状态存储到$_SESSION全局变量中。
- 记住密码: 如果勾选记住密码,则通过setcookie函数设置cookie。
- session保存位置
- 保存位置: session数据可以保存在文件或内存中,具体配置在php.ini文件中设置。
- php.ini配置文件
- 配置参数: session.save_handler用于设置session的保存方式,如files表示保存到文件。
- 校验
- 销毁
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
Session与Cookie的区别 | Session保存在服务端,Cookie保存在客户端 | Session与Cookie的关系和区别 | ★★★ |
Cookie的问题 | 1. 占用客户端过多存储空间<br>2. 增加HTTP通信成本 | Cookie数量过多带来的问题 | ★★ |
Session的实现原理 | 1. 服务端保存用户信息,下发Session ID<br>2. 客户端保存Session ID,每次请求携带 | Session如何减轻客户端负担 | ★★★ |
Session的工作流程 | 1. 用户首次访问,开启会话,保存信息<br>2. 用户后续访问,携带Session ID,校验身份<br>3. 用户注销,销毁会话,Cookie过期 | Session的完整交互流程 | ★★★★ |
Session的存储位置 | 可以保存在磁盘或内存中,如Redis | Session的存储方式及配置 | ★★★ |
Session的应用场景 | 用户登录状态保持、访问追踪等 | Session在实际应用中的作用 | ★★ |
Session与Cookie的对比 | Cookie把内容保存在客户端,全部发送<br>Session把内容保存在服务端,只发Session ID | Cookie与Session的对比总结 | ★★★ |
Session的安全性 | 服务端控制,相对安全,但需防范Session劫持 | Session的安全性及防范措施 | ★★★★ |
PHP中的Session操作 | 1. session_start()开启会话<br>2.$_SESSION全局变量存储信息<br>3. session_destroy()销毁会话 | PHP中Session的具体操作 | ★★★★ |
php代码实现session
在PHP中,Session(会话)是用来在不同页面请求之间存储用户的数据。PHP内置了对Session的支持,允许开发者通过简单的API在服务器端管理会话信息。下面我将详细介绍如何在PHP中实现和使用Session。
1. 开启Session
在PHP中,要使用Session,首先需要调用 session_start()
函数来启动Session。通常这行代码应该放在页面的最开始部分,即所有输出内容之前。
<?php
// 启动Session
session_start();
?>
关键点:
-
session_start()
必须在输出任何内容之前调用,否则会导致"headers already sent"错误。 -
这会自动检查是否已经存在Session ID,如果存在,它会继续处理会话。如果没有,它会生成一个新的Session ID,并将其发送给浏览器。
2. 设置和访问Session数据
一旦Session启动,你可以通过 $_SESSION
超全局变量来存储和访问会话数据。$_SESSION
是一个关联数组,你可以像操作普通数组一样读取或写入数据。
设置Session变量
<?php
// 启动Session
session_start();// 设置Session变量
$_SESSION['username'] = 'JohnDoe';
$_SESSION['user_id'] = 12345;
?>
访问Session变量
<?php
// 启动Session
session_start();// 访问Session变量
echo 'Username: ' . $_SESSION['username']; // 输出: Username: JohnDoe
echo 'User ID: ' . $_SESSION['user_id']; // 输出: User ID: 12345
?>
3. 删除Session数据
如果你想从Session中删除某个变量,可以使用 unset()
函数。
<?php
// 启动Session
session_start();// 删除Session中的特定变量
unset($_SESSION['username']);
?>
如果你想删除所有的Session数据,可以使用 session_unset()
:
<?php
// 启动Session
session_start();// 删除所有Session数据
session_unset();
?>
4. 销毁Session
销毁Session会彻底清除Session的所有数据,并且从服务器端删除Session ID。
-
销毁当前Session数据:
session_unset()
会清除所有Session变量,但不会销毁整个会话。 -
销毁整个Session:
session_destroy()
会销毁整个Session,且不能在当前脚本继续访问Session数据。
<?php
// 启动Session
session_start();// 删除Session变量
unset($_SESSION['username']);// 销毁整个Session
session_destroy();
?>
注意:
-
session_destroy()
通常不会立即删除客户端的Session ID(即Cookie中的PHPSESSID
),但它会导致Session数据在服务器端被销毁。要完全删除Session,需要调用session_unset()
清除所有会话变量。
5. Session ID管理
PHP默认会将Session ID存储在客户端的Cookie中,并通过HTTP请求发送到服务器。如果你需要手动管理Session ID(例如,将Session ID通过URL传递),可以使用 session_id()
函数。
获取当前的Session ID
<?php
// 启动Session
session_start();// 获取当前Session ID
echo 'Session ID: ' . session_id();
?>
手动设置Session ID
<?php
// 设置一个自定义的Session ID(不推荐)
session_id('customSessionID');
session_start();
?>
6. Session过期与生命周期
PHP的Session在默认情况下是会话型的,即浏览器关闭时Session会失效。如果希望设置Session的过期时间,可以通过配置文件或者通过代码来修改session.gc_maxlifetime
来控制Session的生命周期。
配置Session过期时间
你可以在php.ini
中设置Session的过期时间(单位是秒):
session.gc_maxlifetime = 3600 ; 设置Session最大生命周期为1小时
或者在代码中通过 ini_set()
设置:
<?php
// 设置Session最大生命周期为1小时
ini_set('session.gc_maxlifetime', 3600);
session_start();
?>
7. Session存储位置
PHP默认将Session数据存储在服务器的临时目录中(通常是/tmp
目录)。你可以通过配置php.ini
来指定Session数据存储的路径。
配置Session存储路径
session.save_path = "/path/to/custom/directory"
如果你希望使用自定义的存储位置,确保PHP有写入权限。
8. 共享Session存储(分布式环境)
如果你在多台服务器中部署应用(例如负载均衡环境),可以使用以下方法来共享Session数据:
-
使用数据库:你可以将Session存储在数据库中(例如MySQL)。可以通过自定义Session存储处理程序来实现。
-
使用缓存系统:如 Redis 或 Memcached,它们可以提供更高效的Session存储。
示例:使用Redis存储Session
你可以使用 phpredis
扩展来将Session存储在Redis中。配置示例如下:
session.save_handler = redis
session.save_path = "tcp://localhost:6379"
9. 使用Session进行用户认证
Session通常用于用户认证和授权。在用户登录时,你可以将用户的ID或其他信息存储在Session中,之后的请求中可以通过检查Session来确认用户身份。
用户登录示例
<?php
// 启动Session
session_start();// 假设这是用户提交的登录表单
$username = $_POST['username'];
$password = $_POST['password'];// 验证用户名和密码
if ($username === 'admin' && $password === 'password123') {// 登录成功,保存用户信息到Session$_SESSION['username'] = $username;$_SESSION['user_id'] = 1; // 假设用户ID是1echo '登录成功!';
} else {echo '登录失败!';
}
?>
用户验证示例
<?php
// 启动Session
session_start();// 检查用户是否已登录
if (isset($_SESSION['username'])) {echo '欢迎,' . $_SESSION['username'];
} else {echo '请先登录!';
}
?>
10. 安全性考虑
尽管PHP的Session很方便,但也有一些安全性问题需要注意:
-
Session固定攻击(Session Fixation):在用户登录时强制生成新的Session ID,防止攻击者预先知道Session ID。可以使用
session_regenerate_id()
函数:session_regenerate_id(true);
-
Session劫持:通过HTTPS协议传输Session数据,防止Session ID在传输过程中被窃取。
-
防止XSS攻击:确保浏览器不允许通过JavaScript访问Session ID,设置
HttpOnly
属性:session_set_cookie_params(['httponly' => true]);
-
防止CSRF攻击:使用防止跨站请求伪造(CSRF)攻击的技术,例如通过使用CSRF token来验证请求的合法性。