ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## SESSION > 1. `SESSION` 数据存储在服务器,当认证用户增多,会增加服务器开销 > 2. 可扩展`REDIS`存储,当认证用户增多,还是会产生很大的开销,当然也可使用`REDIS`集群 > 3. `SESSION` 依赖于名为`JSESSIONID`的`Cookie`, 当Cookie禁用时,需要手动传递`JSESSIONID`, > > PHP输出`session_id()` > 4. `session.gc_divisor` 与 `session.gc_probability` 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。 > > 此概率用 `gc_probability/gc_divisor` 计算得来。 > > 例如 1/100 意味着在每个请求中有 1% 的概率启动 gc 进程。`session.gc_divisor` 默认为 100。 > > `session.gc_maxlifetime=30`,`session.gc_divisor=1000`,`session.gc_probability=1`,就表示每一千个用户调用`session_start()`的时候,就百分百的会执行一次垃圾回收机制,将磁盘上没用的session文件删除。 ## COOKIE > 1. `COOKIE`数据存储在客户端, > 2. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。 > 3. 容易被劫持,CSRF问题 ## JWT (json web token) >[warning] JWT 的核心是无状态、自验证、无中央服务器,有超时时间等机制,我们所实现的登录功能,本质上是一个状态保持的机制,要保持,就会有断开的需求,JWT 不能实现断开。 > JWT 的核心应用场景根本不是状态保持! > * 当需要令牌加入黑名单时 - 同样需要保存黑名单令牌 - 也会涉及到并发场景 - 以及续签等问题 - 维护黑名单的开销 要比`session`低很多 * Header(头部) > ```{"alg": "HS256","typ": "JWT"}``` * Payload(负载) >``` > iss: jwt签发者 > sub: jwt所面向的用户 > aud: 接收jwt的一方 > exp: jwt的过期时间,这个过期时间必须要大于签发时间 > nbf: 定义在什么时间之前,该jwt都是不可用的. > iat: jwt的签发时间 > jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 > ``` * Signature(签名) >``` >HMACSHA256( > base64UrlEncode(header) + "." + > base64UrlEncode(payload), > secret) >``` ### 存在问题 > 1. 无状态JWT令牌不能无效或更新,并且会根据您存储它们的位置引入大小问题或安全问题。 > 2. 不应该在JWT的`payload`部分存放敏感信息,因为该部分是客户端可解密的部分。 > 3. 保护好`secret`私钥,该私钥非常重要。 > 4. 如果可以,请使用`https`协议 > 如果您担心有人拦截您的会话cookie,您应该只使用`TLS` 如果您不使用`TLS`,任何类型的会话实现都是可以截取的,包括JWT。 除非您使用Reddit规模的应用程序,否则没有理由将JWT令牌用作会话机制,只需使用Session即可。 ### 使用JWT时注意事项 > 1. 令牌是短暂的,它们只需要有效几分钟,以允许客户端启动下载。 > 2. 该令牌只能使用一次,应用程序服务器会为每次下载发出一个新令牌,因此任何一个令牌只用于请求一次文件,然后被丢弃,没有持久化状态。 > 3. 应用程序服务器仍使用会话,只是下载服务器使用令牌来授权单个下载,因为它不需要持久状态。 >> 结合Session和JWT Token是完全合理的。它们各有各的目的,有时你需要两者。不要给需要持久化、长期保存的数据使用JWT。