xp-forge / cookie-sessions
基于Cookie的会话
v0.3.0
2024-03-24 10:26 UTC
Requires
- php: >=7.0.0
- xp-forge/sessions: ^3.0
- xp-framework/core: ^12.0 | ^11.0 | ^10.0
Requires (Dev)
- xp-framework/test: ^2.0 | ^1.0
README
为sessions库提供的基于Cookie的会话实现。纯客户端,无需服务器端存储,因此可很好地扩展。然而,它也带来了缺点,如下文所述。
使用方法
在路由设置内部
use web\session\CookieBased; use web\auth\SessionBased; use util\Secret; $secret= new Secret('y+lCLaMzxlnHjkTt3FoPVQ_x5XTHSr78'); // 32 bytes! $sessions= new CookieBased($secret); $auth= new SessionBased($flow, $sessions); return $auth->required(function($req, $res) { // Use $req->value('user') });
可以使用以下方法生成一个二进制安全的32字节密钥
$ xp -d 'base64_encode(random_bytes(24))' string(32) "ai4BO6rpwgezJztTalg5rt29XNJwMRMQ"
安全性
如此处所述
将会话数据放入会话Cookie的安全性风险是“会话重放”攻击的危险。如果从用户的浏览器中捕获了一个有效的会话Cookie(它在浏览器的开发者控制台中可见),那么该Cookie可以被复制到另一台机器,并在任何时间用于恶意会话。
尽管相同的攻击也适用于通过Cookie传输会话ID的服务器端会话,但我们可以在这些情况下通过删除会话文件或从数据库中删除相关行来在服务器端销毁附加的会话。对于基于Cookie的会话,没有远程保证销毁会话的方法——因此没有保证用户安全地“在所有设备上注销”的功能。
然而,如果我们使用基于Cookie的会话来存储短期访问令牌,我们可以显著降低这种风险:重放只能在这个时间段内发生。对于Microsoft 365,这个时间大约是一个小时。
👉 简而言之:如果使用服务器端会话很容易,就那样做。如果依赖关系成本很高,并且你有管理风险的方法,或者用于开发目的,这种实现可以是一个有效的选择。
内部结构
会话数据在Cookie中被加密,然后使用base64编码以使用7位编码。第一个字节控制使用的算法
S
代表Sodium,使用sodium_crypto_box_open(),需要Sodium扩展O
代表OpenSSL,使用openssl_encrypt(),需要OpenSSL扩展
加密值由哈希签名,以检测任何位翻转攻击。
压缩
为了防止过早地触及浏览器Cookie限制,如果认为值得,则使用LZW(它相对容易实现,并且在不要求编译额外的PHP扩展的情况下提供良好的节省)对Cookie值进行压缩。如果Cookie值被压缩,上述指示符将显示为小写(s
和o
而不是S
和O
)。
一个示例
- JSON值(来自
https://api.twitter.com/1.1/account/verify_credentials.json
的响应):2814字节 - 加密和编码后的Cookie值:3807字节(非常接近限制!)
- 如果压缩,则减少到2477字节(节省超过一千字节,大小为65%)