認證 / 受權web
認證解決了「你是誰」的問題。
受權解決了「你能作什麼」的問題。後端
對於通常的web應用,咱們知道 HTTP 是無狀態的,因此客戶端和服務端須要解決的如何讓之間的對話變得有狀態。例如只有是登錄狀態的用戶纔有權限調用某些接口,那麼在用戶登錄以後,須要記住該用戶是已經登錄的狀態。常見的方法是使用 session 機制
常見的 session 模型是這樣工做的:api
理論上來講 ,JWT 機制能夠取代 session 機制。用戶不須要提早進行登錄,後端也不須要 Redis 記錄用戶的登錄信息。客戶端的本地保存一份合法的 JWT, 當用戶須要調用接口時,附帶上該合法的 JWT,每一次調用接口,後端都使用請求中附帶的 JWT 作一次合法性的驗證。這樣也間接達到了認證用戶的目的瀏覽器
然而 JWT 真的能取代 session 機制嗎?這麼作有哪些好處和壞處?安全
JWT 的目的不是爲了隱藏或者保密數據,而是爲了確保數據確實來自被受權的人建立的(不被篡改)微信
回想一下,當你拿到 JWT 時候,你徹底能夠在沒有 secret 的狀況下解碼出 header 和 payload,由於 header 和 payload 只是通過了 base64 編碼(encode)而已,編碼的目的在於利於數據結構的傳輸。雖然建立 signature 的過程近似於加密 (encrypt),但本質實際上是一種簽名 (sign) 的行爲,用於保證數據的完整性,實際上也而且並無加密任何數據restful
傳統的 session+cookie 方案用戶點擊註銷,服務端清空 session 便可,由於狀態保存在服務端。但 jwt 的方案就比較難辦了,由於 jwt 是無狀態的,服務端經過計算來校驗有效性。沒有存儲起來,因此即便客戶端刪除了 jwt,可是該 jwt 仍是在有效期內,只不過處於一個遊離狀態。cookie
修改密碼則略微有些不一樣,假設號被到了,修改密碼(是用戶密碼,不是 jwt 的 secret)以後,盜號者在原 jwt 有效期以內依舊能夠繼續訪問系統,因此僅僅清空 cookie 天然是不夠的,這時,須要強制性的修改 secret。session
咱們知道微信只要你天天使用是不須要從新登陸的,由於有token續簽,由於傳統的 cookie 續簽方案通常都是框架自帶的,session 有效期 30 分鐘,30 分鐘內若是有訪問,session 有效期被刷新至 30 分鐘。可是 jwt 自己的 payload 之中也有一個 exp 過時時間參數,來表明一個 jwt 的時效性,而 jwt 想延期這個 exp 就有點身不禁己了,由於 payload 是參與簽名的,一旦過時時間被修改,整個 jwt 串就變了,jwt 的特性自然不支持續簽!數據結構
一次性驗證
好比用戶註冊後須要發一封郵件讓其激活帳戶,一般郵件中須要有一個連接,這個連接須要具有如下的特性:可以標識用戶,該連接具備時效性(一般只容許幾小時以內激活),不能被篡改以激活其餘可能的帳戶
這種場景就和 jwt 的特性很是貼近,jwt 的 payload 中固定的參數:iss 簽發者和 exp 過時時間正是爲其作準備的。
Web 應用中使用 JWT 是讓應用變得更復雜了。在 web 應用中,絕大多數狀況下,傳統的 cookie-session 機制工做得更好。jwt 適合作簡單的 restful api 認證,頒發一個固定有效期的 jwt,下降 jwt 暴露的風險,不要對 jwt 作服務端的狀態管理,這樣才能體現出 jwt 無狀態的優點。