Loading... [JWT](https://jwt.io/) ## 无状态 Cookie + Session 的鉴权方案会在服务端创建一个数据持久层来存储会话信息 JWT 鉴权是无状态的, 不需要数据持久层即可实现鉴权 --- ## JWT JWT 使用一个 Secret (密钥 ) 来进行签发 通过比对签发后的 JWT 来判断是否拥有权限 ```mermaid --- title: JWT 鉴权 --- graph LR 1((客户端)) --登录--> 2[服务端] 2 --签发JWT--> 1 3((客户端)) --- 4["访问 (携带JWT)"] 4 --> 5[服务端] 5 --> 7{验签} 7 --N--> 8[不予访问] 7 --Y--> 3 ``` --- ## Cookie + Session 服务端的鉴权一般采用的是 Cookie + Session 来实现的: 客户端的 Cookie 储存 SessionID, 服务器通过查询数据持久层的 SessionID 来判断用户是否登录 ```mermaid --- title: Cookie + Session 鉴权流程 --- graph LR 1((客户端)) --登录--> 2[服务端] 2--生成并存储---> 3(SessionID) 3 --Cookie----> 1 4((客户端)) --- 9["访问(携带 Cookie)"] 9 --> 5[服务端] 5 --> 6[查询SessionID] 6 --> 7{是否存在} 7 --N--> 8[不予访问] 7 --Y--> 4 ``` 采用这种方案, 服务端要维护一个数据持久层, 且随着登录用户的增加, 数据持久层会变得越来越大 同时, 如果数据持久层出现崩溃, 鉴权就会失败 --- ### SessionID 的生成 #### PHPSESSIONID PHPSESSIONID 的生产算法原理: 1. `hash_func = MD5 / SHA1` 可由 `php.ini` 配置 2. `PHPSESSIONID = hash_func( 客户端IP + 当前时间戳(秒)+ 当前时间戳(微秒) + PHP自带的随机数生产器 )` 从以上 `hash_func(...)` 中的数据采样值可以看出,多个用户在同一台服务器时所生产的PHPSESSIONID重复的概率极低 另外, 黑客如果要猜出某一用户的PHPSESSIONID, 则他也必须知道“客户端IP, 当前时间 (秒, 微妙), 随机数”等数据才能模拟 > 参考: [PHP中Session ID的实现原理分析和实例解析](https://cloud.tencent.com/developer/article/1677270) --- session 无法跨域, JWT 可以? JWT 一般放在 Header 中的 `Authorization` 字段中 (B 站则是放在Cookie中的bili\_ticket中) --- ## 使用 JWT ### NodeJS 利用 `jsonwebtoken` 库来实验 JWT 的签发 ```bash npm install jsonwebtoken ``` 创建 `main.mjs` 文件: ```javascript import jsonwebtoken from 'jsonwebtoken' const { verify, sign } = jsonwebtoken const SECRET = "123456" // 签名 JWT const token = sign({ id: 'voilone', message: '可以添加自定义字段, 但不能是敏感信息' }, SECRET, { expiresIn: "1d" }) // 验签 try { const verifiedInfo = verify(token, SECRET) console.log("鉴权成功:", verifiedInfo); } catch (e) { console.log("鉴权失败"); } ``` --- `<div class="hideContent">该部分仅登录用户可见</div>` 最后修改:2024 年 05 月 09 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏