一些關(guān)鍵詞: cookie / request / headers / session / jwt / token / sessionStorage
問題: 客戶端把登錄密匙( sessionId 或 jwt )放在 cookie VS request headers 里:
cookie 與 request headers, 本身都是 request 請(qǐng)求的信息載體
1. 放 cookie 里:
- 缺點(diǎn): cookie 本身有存儲(chǔ)容量上限小 5kb,
- 缺點(diǎn): 每次 request 請(qǐng)求都攜帶 cookie,
- 缺點(diǎn): cookie 不能跨域名, 不能實(shí)現(xiàn)點(diǎn)單登錄
- 優(yōu)點(diǎn): 服務(wù)端通過設(shè)置 httpOnly 客戶端不可以修改密匙
- 優(yōu)點(diǎn): 想的少, 放里就完了, 請(qǐng)求每次都攜帶
2. 放 request headers 里:
- 優(yōu)點(diǎn): 如果存在 sessionStorage 里, 容量上限 5mb,
- 優(yōu)點(diǎn): 每次 request 請(qǐng)求可以判斷是否攜帶,
- 優(yōu)點(diǎn): 可以跨域名, 可以實(shí)現(xiàn)點(diǎn)單登錄
- 缺點(diǎn): 無 httpOnly 功能, 客戶端可以修改
- 缺點(diǎn): 靈活意味著事兒也多
| 跨域 | 單點(diǎn)登錄 | 設(shè)置 httpOnly | 請(qǐng)求攜帶 | 存儲(chǔ)容量 | |
|---|---|---|---|---|---|
| cookie | 不能 | 不能 | 可以 httpOnly, 相對(duì)更安全 | 必須攜帶 | cookie 5bk |
| request headers | 可以 | 可以 | 不能 httpOnly, 相對(duì)有危險(xiǎn) | 可以判斷 | 若放在 sessionStorage 上限為 5mb |
問題: 登錄解決方案 session VS jwt:
session 與 jwt 本身都是密匙, 都存放著某些敏感信息, 都需要設(shè)置過期時(shí)間, 不同的是
session:
- sessionId 本身是一個(gè)密匙, 是通過服務(wù)端動(dòng)態(tài)生成的
- sessionId 本身不帶有 用戶信息, 需要用 sessionId 跑到 redis 里拿到 userInfo
- session 對(duì)象是通過服務(wù)端管理的, 一般都放在 redis 里
- 關(guān)于單點(diǎn)登錄方面, 放在 cookie 里不能實(shí)現(xiàn), 放在 request headers 可以實(shí)現(xiàn)
- session 本身依賴 redis 管理, 所以可以在服務(wù)端操作用戶登錄狀態(tài)
- 業(yè)內(nèi)公認(rèn) 可拓展性 jwt 比 session 好, 因?yàn)?jwt 本身就攜帶 userInfo 信息, 可以在不同的域名里傳遞.
- session 安全性高, 因?yàn)?sessionId 在客戶端存的內(nèi)容比 jwt 少, 且 sessionId 一般存在 cookie 里, cookie 可以設(shè)置 httpOnly. jwt 一般存在 sessionStorage 里, 客戶端可以修改
- RESTful 規(guī)范要求 請(qǐng)求無狀態(tài) 規(guī)范, jwt 要本身就是無狀態(tài)的
- session 請(qǐng)求攜帶量小, 但每次請(qǐng)求都攜帶, 之后還要去 redis 里去查 userInfo. jwt 請(qǐng)求攜帶量大, request 后不需要再去 redis 里查找, 本身就是 userInfo, 用空間換時(shí)間.
- 時(shí)效性應(yīng)用場(chǎng)景: 用戶在系統(tǒng)中濫用權(quán)限, 管理員對(duì)用戶降級(jí)處理. 賬號(hào)在異地登錄, 使賬號(hào)強(qiáng)制登出. 這些場(chǎng)景 session 比 jwt 好用.
jwt( json web token ):
- jwt 本身是一個(gè)密匙, 是通過服務(wù)端加密算出的
- jwt 本身就攜帶 用戶信息, 所以不需要用到 redis
- token 字符串里包含所有的 用戶信息, 不需要 redis, 所以服務(wù)端也很難管理( 如: 強(qiáng)制登出某用戶, 若用黑名單實(shí)現(xiàn)需要記錄此用戶的下次請(qǐng)求動(dòng)作 )
- 關(guān)于單點(diǎn)登錄方面, 放在 cookie 里不能實(shí)現(xiàn), 放在 request headers 可以實(shí)現(xiàn)
- jwt 不需要 redis, 在服務(wù)端管理比較難
| 密匙信息 | 在客戶端的字符串 | redis依賴 | 單點(diǎn)登錄 | 服務(wù)端管理 | 可拓展性 | 安全性 | RESTful | 性能 | 時(shí)效性 | |
|---|---|---|---|---|---|---|---|---|---|---|
| session | sessionId 就是一個(gè)動(dòng)態(tài)生成的臨時(shí) key | 不是一層不便的 | 依賴 | 能實(shí)現(xiàn) | 相對(duì)好管理 | 良 | 優(yōu) | 語法上也能實(shí)現(xiàn) | 優(yōu) | 優(yōu) |
| jwt | token 包含所有用戶信息 | 不是一層不便的 | 不依賴 | 能實(shí)現(xiàn) | 相對(duì)難管理 | 優(yōu) | 良 | 支持無狀態(tài)規(guī)范 | 良 | 良 |