JSON Web Token 入門教程

作者: 阮一峰

日期: 2018年7月23日

騰訊課堂 NEXT 學院

JSON Web Token(縮寫 JWT)是目前最流行的跨域認證解決方案,本文介紹它的原理和用法。

一、跨域認證的問題

互聯網服務離不開用戶認證。一般流程是下面這樣。

1、用戶向服務器發送用戶名和密碼。

2、服務器驗證通過后,在當前對話(session)里面保存相關數據,比如用戶角色、登錄時間等等。

3、服務器向用戶返回一個 session_id,寫入用戶的 Cookie。

4、用戶隨后的每一次請求,都會通過 Cookie,將 session_id 傳回服務器。

5、服務器收到 session_id,找到前期保存的數據,由此得知用戶的身份。

這種模式的問題在于,擴展性(scaling)不好。單機當然沒有問題,如果是服務器集群,或者是跨域的服務導向架構,就要求 session 數據共享,每臺服務器都能夠讀取 session。

舉例來說,A 網站和 B 網站是同一家公司的關聯服務。現在要求,用戶只要在其中一個網站登錄,再訪問另一個網站就會自動登錄,請問怎么實現?

一種解決方案是 session 數據持久化,寫入數據庫或別的持久層。各種服務收到請求后,都向持久層請求數據。這種方案的優點是架構清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。

另一種方案是服務器索性不保存 session 數據了,所有數據都保存在客戶端,每次請求都發回服務器。JWT 就是這種方案的一個代表。

二、JWT 的原理

JWT 的原理是,服務器認證以后,生成一個 JSON 對象,發回給用戶,就像下面這樣。


{
  "姓名": "張三",
  "角色": "管理員",
  "到期時間": "2018年7月1日0點0分"
}

以后,用戶與服務端通信的時候,都要發回這個 JSON 對象。服務器完全只靠這個對象認定用戶身份。為了防止用戶篡改數據,服務器在生成這個對象的時候,會加上簽名(詳見后文)。

服務器就不保存任何 session 數據了,也就是說,服務器變成無狀態了,從而比較容易實現擴展。

三、JWT 的數據結構

實際的 JWT 大概就像下面這樣。

它是一個很長的字符串,中間用點(.)分隔成三個部分。注意,JWT 內部是沒有換行的,這里只是為了便于展示,將它寫成了幾行。

JWT 的三個部分依次如下。

  • Header(頭部)
  • Payload(負載)
  • Signature(簽名)

寫成一行,就是下面的樣子。


Header.Payload.Signature

下面依次介紹這三個部分。

3.1 Header

Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常是下面的樣子。


{
  "alg": "HS256",
  "typ": "JWT"
}

上面代碼中,alg屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌統一寫為JWT

最后,將上面的 JSON 對象使用 Base64URL 算法(詳見后文)轉成字符串。

3.2 Payload

Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的數據。JWT 規定了7個官方字段,供選用。

  • iss (issuer):簽發人
  • exp (expiration time):過期時間
  • sub (subject):主題
  • aud (audience):受眾
  • nbf (Not Before):生效時間
  • iat (Issued At):簽發時間
  • jti (JWT ID):編號

除了官方字段,你還可以在這個部分定義私有字段,下面就是一個例子。


{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

注意,JWT 默認是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。

這個 JSON 對象也要使用 Base64URL 算法轉成字符串。

3.3 Signature

Signature 部分是對前兩部分的簽名,防止數據篡改。

首先,需要指定一個密鑰(secret)。這個密鑰只有服務器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產生簽名。


HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出簽名以后,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,就可以返回給用戶。

3.4 Base64URL

前面提到,Header 和 Payload 串型化的算法是 Base64URL。這個算法跟 Base64 算法基本類似,但有一些小的不同。

JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字符+/=,在 URL 里面有特殊含義,所以要被替換掉:=被省略、+替換成-/替換成_ 。這就是 Base64URL 算法。

四、JWT 的使用方式

客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。

此后,客戶端每次與服務器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面。


Authorization: Bearer <token>

另一種做法是,跨域的時候,JWT 就放在 POST 請求的數據體里面。

五、JWT 的幾個特點

(1)JWT 默認是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。

(2)JWT 不加密的情況下,不能將秘密數據寫入 JWT。

(3)JWT 不僅可以用于認證,也可以用于交換信息。有效使用 JWT,可以降低服務器查詢數據庫的次數。

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

(5)JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權限。為了減少盜用,JWT 的有效期應該設置得比較短。對于一些比較重要的權限,使用時應該再次對用戶進行認證。

(6)為了減少盜用,JWT 不應該使用 HTTP 協議明碼傳輸,要使用 HTTPS 協議傳輸。

六、參考鏈接

(完)

留言(108條)

可以說講的很清楚了

沒質量,這種網上一抓一大把。

無狀態的東西好在方便擴展,例如map reduce。不過通常服務器還是需要對session或者token有比較高的掌控權。JWT還是用在一些不那么需要保證安全的地方會好一些例如確認退訂郵件等。

看懂了,哈哈,算是入門了嗎?

清晰簡潔,????

如今安全越來越重要,客戶端儲存永久token,是否有它適用的場景?

最近的博客質量不高啊,不過高質量的博文不常有,為了保證文章數量,只能這樣了。

引用moyo的發言:

沒質量,這種網上一抓一大把。

這都能酸..

引用令狐洋蔥的發言:

如今安全越來越重要,客戶端儲存永久token,是否有它適用的場景?

并沒建議讓永久儲存token啊. 看特點的第5條

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

對于行外人來說,喜歡了解這樣的原理性的東西。實話講,我雖然看不懂,但是希望了解框架知識就夠了。

引用moyo的發言:

沒質量,這種網上一抓一大把。

大哥啊,別噴了,如果你懂,那么請你默默的離開,簡單明了本身就是質量。

感覺缺點大于優點。

完全不懂的我竟然看懂了 誰敢說沒質量!!!

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

JWT最大特點不就是狀態存儲在客戶端么,可以實現多點登錄,服務端不用做很多的額外工作

很好,看懂了.

session和jwt都有各自的使用場景,并不是一概而論好壞,各自都有優缺點,取長補短就行了

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

不引入數據庫支持的話這個的確沒法實現。最好的方案是維護一張基于 jti (JWT ID) 的表,將jti和user_id關聯起來,生成新的jwt時將該user_id舊的jwt標記為失效就好,具體場景還得看你們的具體業務邏輯。

jwt主要還是用在移動端的

引用moyo的發言:

沒質量,這種網上一抓一大把。

有一個老乞丐,天天到捷運站磕頭乞討,小白每次經過,固定都會給他二十元,每天下班遇到就給,這樣持續了一年。
?
有一天,小白只給乞丐十元,乞丐愣了一下,但還是勉強抬頭笑了笑。
?
隔天,小白又給十元。再隔天,又是十元。
?
到了第七天,老乞丐終于忍不住了,伸手拉住小白說:「以前你都給二十,怎么現在都只給十元?」
?
小白被抓住,有點吃驚,旋即回過神來說:「啊,抱歉,我結婚了,要省著點。」
?
乞丐怒得一巴掌打過去:「什么玩意]

引用moyo的發言:

沒質量,這種網上一抓一大把。

軟一峰絕對不是編程界代碼寫的最厲害的,但他一定是編程界教程寫的最好的

寫的好,簡單明了

通俗易懂~ 小白有個疑問望各位大神解答:
用jwt來實現 跨域單點登錄:
①A系統登錄成功—>jwt 返回tokemn ->客戶端保存至 cookie
②同一瀏覽器進入B 系統-> 瀏覽器提交token ->服務器驗證token 是否有效 ->有效B系統自動登陸用戶

問:1) jwt 不易保存私密信息,A登陸后 必然將用戶部分信息存儲至 token B才能獲取是哪位用戶?
2) B驗證token 驗證登陸后 不在b系統中產生sesion ?

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

簽名可以加時間戳或這其他隨機參與加密,一旦登錄就更新簽名,之前的簽名失效,不會出現多個在線啦

客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage

瀏覽器存在 cookie 中的token 跨域也是非共享的, A系統登錄后,瀏覽器訪問B 怎么拿到這個token?

JWT的幾個特點中第四條,除非服務器部署額外的邏輯,能不能舉例說明下,有點困惑

@優惠券:

你可以讓他對比維護是否簽發token的清單和維護session列表哪個更容易一些,如果在這方面JWT沒有優勢,也就沒有重新發明的必要額。

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

JWT 解決的最大問題是跨域,如果你們的業務不涉及跨域完全沒有必要用JWT session 就夠用了,如果有跨域需要,那么改造Session實現跨域訪問,要比改造JWT實現單用戶登陸復雜的多

引用stong的發言:

通俗易懂~ 小白有個疑問望各位大神解答:
用jwt來實現 跨域單點登錄:
①A系統登錄成功—>jwt 返回tokemn ->客戶端保存至 cookie
②同一瀏覽器進入B 系統-> 瀏覽器提交token ->服務器驗證token 是否有效 ->有效B系統自動登陸用戶

問:1) jwt不易保存私密信息,A登陸后 必然將用戶部分信息存儲至 token B才能獲取是哪位用戶?
2)B驗證token 驗證登陸后 不在b系統中產生sesion ?

使用JWT用戶數據由客戶端傳入,每個請求都會帶著這些信息,也就不需要后端生成Session了,在每次請求的時候驗證登陸狀態及登陸用戶

阮老師,不聊聊yimiao時間嗎

等了好久阮老師終于也寫jwt了,之前網上查的確實沒阮老師寫的易懂。

引用小白的發言:

客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage

瀏覽器存在 cookie 中的token 跨域也是非共享的, A系統登錄后,瀏覽器訪問B怎么拿到這個token?

跨域這塊,前端也是要處理的,兩種情況:

1. token 存儲在 cookie 里,按傳統的跨域方案,共享/傳遞 cookie 里的 token
2. token 存儲在 localStorage 里,則需要 localStorage 的跨域方案,以便 共享/傳遞 cookie 里的 token,localStorage 的跨域方案可以搜搜,有開源類庫

周五了,催更了,哈哈哈

@優惠券:

如果是移動端的話,可以考慮簽發的時候加入手機的設備編號作為驗證。

JWT是否只是提供一種思路模式,并沒有實際的什么依賴需要添加到系統中,文章中寫的官方提供的7個字段以及簽名算法是否其實并沒有實際的效果,其實只是類似一種規范而已,而開發者自己根據規范去實現?

能否講解一下,JWT跨二級域名記錄登錄狀態時怎么實現同步登錄和退出,之前項目token是存在sessionStorage里面的,但是為了跨二級域名登錄,沒找到實現的方法就放到了cookie里面,感覺有點不太好,有沒有不放到cookie的解決辦法

博客寫得很好,很喜歡

引用moyo的發言:

沒質量,這種網上一抓一大把。

是一抓一大把 但是寫的調理這么清楚的只有一家。我之前也做過jwt token的項目,去看英文的文章很多篇才弄清楚的。

引用令狐洋蔥的發言:

如今安全越來越重要,客戶端儲存永久token,是否有它適用的場景?

沒讓你永久儲存啊,何況你永久儲存那也是你的事情,但是啥時候過期是服務端實現啊,你拿著過期的token請求api,會返回錯誤

@優惠券:

使用jwt的場景是前后端徹底分離,無法通過session來認證的。默認的確是可以多次登錄,發了多個token,也能改成只發一個啊,讓前面的失效,這和session是2回事情。拒絕使用jwt那么授權接口怎么知道是哪個用戶在請求?

引用CCTV的發言:

jwt主要還是用在移動端的

還可以用于前后端分離,對后端來說,沒有移動端不移動端的概念,反正你們都是調用接口,我管你是pc,h5 or app

@stong:

1.其實jwt里面有加密的uid,或者是uid的對應關系

2.b系統產生不產生session,是你b系統的驗證登錄邏輯決定啊,你要從session驗證用戶,那就要寫session,你如果是從redis驗證token,就不需要寫session

@小白:

可以去參考CAS的方案。或者我簡單說一下ucenter的方案,a系統登錄后,拿到了jwt,訪問一下b系統的一個鏈接,由b系統的此鏈接將jwt存入localStorage

引用Aecced的發言:

JWT的幾個特點中第四條,除非服務器部署額外的邏輯,能不能舉例說明下,有點困惑

第四條是JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。?

其實第四條說的有點絕對了,原文第四條的意思應該是jwt頒發后,一般擴展包沒提供讓其失效方法。但是要讓jwt失效依然很簡單,因為jwt一般會放在redis或者mysql表,只要邏輯上去找到uid對應的jwt,刪了就可以了。

引用ixx的發言:

JWT 解決的最大問題是跨域,如果你們的業務不涉及跨域完全沒有必要用JWTsession 就夠用了,如果有跨域需要,那么改造Session實現跨域訪問,要比改造JWT實現單用戶登陸復雜的多

個人認為jwt解決最大的問題不是跨域,而是前后端分離后,純接口方面的用戶認證問題。

引用缺木的發言:

JWT是否只是提供一種思路模式,并沒有實際的什么依賴需要添加到系統中,文章中寫的官方提供的7個字段以及簽名算法是否其實并沒有實際的效果,其實只是類似一種規范而已,而開發者自己根據規范去實現?

如你所說,jwt是一種規范,你也可以不按那個字段走,但是不用自己實現,你可以去全球最大的交友網站github上找到你要用,一般別人寫的都按規范走了,而且方法都已封裝好。

jwt 驗證怎么才能夠防止重放攻擊呢? 最近正在重構自己的個人網站,想做的更安全一點,有人說用挑戰應答?有人說用timeStamp + nonce? 有哪位同仁能解答一下嗎?

@清啟:

`但是要讓jwt失效依然很簡單,因為jwt一般會放在redis或者mysql表,只要邏輯上去找到uid對應的jwt,刪了就可以了。`

你這個不就是額外的邏輯了

@mm:

哈哈,說的真好!話說阮老師有沒有捐贈地址啥的。看了挺多好文章了。

@優惠券:

1. session+jwt 結合
2. session 只存:uid:lastTime, 別什么數據都往session 丟。用lastTime確定是否過期
3. 密碼修改、A/B登錄,lastTime都要更新。
4. 類似騰訊這種,同時支持pc+mobile,就用:uid:{pc:lastTime, mobile:lastTime}

很簡單明了,看了就懂,贊

通俗易懂 ~ 可以說說 refresh token 嗎?

那是不是一旦黑客截取到JWT就意味著在有效期內就可以為所欲為了?

我覺得只有在安全要求一般,且需要跨域的情況下才可以考慮JWT技術。

畢竟JWT簽發后確實是服務器無法控制,如果你非得要通過維護一張JWT id表單來控制JWT失效,那和session比沒有任何優勢,反而還引入了安全性問題,得不償失。

至于說到集群共享session的問題,通過分布式redis應該是可以很好的解決這一問題。

@BobDu:

JWT簽發之后為什么要用JWT id表?JWT里面帶失效時間不就行了?只要私鑰不泄露又沒法偽造。

引用WalkingSun的發言:

簽名可以加時間戳或這其他隨機參與加密,一旦登錄就更新簽名,之前的簽名失效,不會出現多個在線啦

難道每個用戶一個secret ?

哪位大佬能講一下怎么把token放入HTTP 請求的頭信息Authorization字段里面........求解(最好有代碼)

阮老師的博客能推送微信公眾號就更好了,能更方便更及時的看到。。

引用hejg的發言:

阮老師的博客能推送微信公眾號就更好了,能更方便更及時的看到。。

RSS訂閱了解一下

阮老師的語文水平和我的一樣高,因為我能讀懂。

大神,清晰、簡潔,要是能要實際應用例子就更好了,手動點贊

引用小白的發言:

客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage

瀏覽器存在 cookie 中的token 跨域也是非共享的, A系統登錄后,瀏覽器訪問B怎么拿到這個token?

如果你要訪問B的時候攜帶 Token 過去,那把 Token 放在 Header參數,Url的Path參數,Query參數,Body參數都可以傳過去,不一定非要放在 cookie 里面啊, Token 一般還是放在請求頭里面的

@優惠券:

oauth2 了解一下

@優惠券:

應用服務器端保留用戶的最新token即可。

引用moyo的發言:

沒質量,這種網上一抓一大把。

有質量的人會能說出來你這樣的話?
JWT本來就這點東西,怎么算有質量?

博主介紹了如何生成token,卻沒有介紹server端收到token之后如何驗證啊

引用diamond的發言:

博主介紹了如何生成token,卻沒有介紹server端收到token之后如何驗證啊

我也想問這個問題

引用WalkingSun的發言:

簽名可以加時間戳或這其他隨機參與加密,一旦登錄就更新簽名,之前的簽名失效,不會出現多個在線啦

那不是服務器還要保存簽名?

通俗易懂。站在你的肩膀上,我可以看的更遠。感謝!

這是翻譯官方的吧

引用Simon的發言:

這都能酸..

不愿看就悄悄走開,沒有開源分享精神還跑出來指點江山。。。

引用Simon的發言:


這都能酸..


Sorry,剛來引用錯了,我是支持您懟那個嘴欠moyo的“沒質量,這種網上一抓一大把。”的傻評論

請問payload是什么作用,為什么出現2遍(payload、signature)。
只有加密的不行嗎?

“舉例來說,A 網站和 B 網站是同一家公司的關聯服務。現在要求,用戶只要在其中一個網站登錄,再訪問另一個網站就會自動登錄,請問怎么實現?

一種解決方案是 session 數據持久化,寫入數據庫或別的持久層。各種服務收到請求后,都向持久層請求數據。這種方案的優點是架構清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。”

請教一下,session數據持久化怎么能解決“A 網站和 B 網站是同一家公司的關聯服務。現在要求,用戶只要在其中一個網站登錄,再訪問另一個網站就會自動登錄”這個問題呢?A網站和B網站cookie不共享啊。

簡單明了,謝謝。

后端用redis或數據庫記錄一個用戶id到token的對應表,token不用有任何意義,也不需要加密解密,隨機字符串即可。

客戶端發送token的方法跟JWT一樣,可以選擇用cookie、header或url參數,服務器校驗根據 seesion -> 用戶id 的公共存儲判斷。這樣可以很簡單地在后臺根據用戶最后訪問時間更新token有效時間和自動刪除過期token ,還能通過這個表查看在線用戶,這些都是JWT不具備的功能。

所以我看不出JWT相比這個方案有什么好處,除了能節約服務器上 token 到 用戶ID 表的這一次查詢,還有其他好處嗎? 而且一般業務請求,除了拿到用戶ID,還有更多需要服務器調用的服務,比如拿到用戶完整對象、用戶權限、用戶業務操作對象等等,這些不比 查詢 token 到用戶ID表的開銷大得多嗎?

請大伙指正。

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

無法反駁

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

在數據庫里或服務端存儲機構保存用戶等陸狀態,如果登錄狀態發生變化,則重新簽發一個包含登錄狀態碼的JWT給客戶端,原來的A設備因為登錄狀態碼對不上號而被退出,A設備退出后,如果再次登錄時再次重新簽一個包含登錄狀態碼的JWT給客戶端,這樣A手機重新登錄后,B手機因為登錄狀態碼對不上而被退出。

注意下:每次使用登錄功能登錄時登錄時,客戶端向服務端提交登錄數據時,會連同發送重新設定登錄狀態碼的指令,登錄狀態碼為隨機字符串。

這是我的想法,哈俁,大神不要噴,畢竟我是新的人。

什么時候能講講jhipster相關的東西呢阮老師

阮大神些的教程是我見過最易懂的。沒有之一。贊一個!!!

@hengsha:

數據庫掛了呢,用戶量大需要的空間又是多大。

JWT的作用是什么? 他就是用來在兩個獨立系統間建立信任而不需要服務端之間進行通訊. 建立信任之后,你的服務器該做什么session還是要做的.
A為業務系統
B為授信系統

認證過程
A打開B 傳入A的標識進行登錄授權,B根據A的標識使用對應TOKEN生成JWT
A獲取到JWT,進行校驗,匹配的情況下,A生成SESSION返回瀏覽器前端
退出登錄過程
A收到退出登錄請求,或者關閉瀏覽器,session失效,下次登錄重復此流程

引用優惠券的發言:

(4)JWT 的最大缺點是,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

也就是說一個用戶在手機A中登錄了,然后又在手機B中登錄,在過期之前手機A和B都可以登錄,無法做到B登錄后讓A過期,如果要做到這點,就必須讓服務器維護一個清單(記錄該賬號是否已經簽發token),這樣又回到session的老路了

以上就是我們公司后端拒絕使用jwt的理由,我該怎么駁倒他?

防止重復登陸,都是通過其他策略,例如:互斥ip控制,互斥設備控制等。token更多的是認證,而不是防重復。

"舉例來說,A 網站和 B 網站是同一家公司的關聯服務。現在要求,用戶只要在其中一個網站登錄,再訪問另一個網站就會自動登錄,請問怎么實現?

一種解決方案是 session 數據持久化,寫入數據庫或別的持久層。各種服務收到請求后,都向持久層請求數據。這種方案的優點是架構清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。"

個人感覺這種解決方案不是解決單點登錄問題。單點登錄問題的核心是如何讓瀏覽器擁有目標網站的會話標識。

阮老師的文章從來都是這么通俗易懂,中文教程中最實用的入門內容

@hengsha:

你的策略很好,我喜歡。

但是,試想,如果在你這套機制之上,將無意義的token換成JWT, 在一些需要顯示用戶昵稱、頭像的場景(不敏感場景),減少一次數據庫查詢,又何嘗不可呢? (對于需要使用JWT里面的敏感數據如用戶ID時,你就查一下數據庫唄。)

那你可能會提出,那我就將我那一串無意義的token換成有意義的昵稱、頭像,不就好了嗎。對于這個問題,你要試想,你沒有簽名,黑客就能偽造昵稱、頭像甚至是用戶ID,然后提交到服務器上,服務器上也會接收這個昵稱、頭像甚至是用戶ID,那就麻煩大了。

那你可能會提出,那我也搞一個簽名,防止黑客偽造不就行了?那你不覺得,你這就是JWT嗎,當然你可能不是JSON格式的,那就是AWT、BWT、CWT、XWT,隨便啦,其實最終就都是一樣的東西了。

JWT跟跨域有個啥的關系。。。。。。。。

引用moyo的發言:

沒質量,這種網上一抓一大把。

網上肯定有類似的東西,但是阮老師講的言簡意賅,且易懂

槽點太多,JWT和跨域有什么關系??BASE64是加密算法?TOKEN放到url里是因為要滿足URL規范所以要urlencode 可是這和BASE64有什么關系?

有個問題 假如A網站登入后B網站要自動登錄,前端把數據存在哪里 不管是cookie 還是 localstorage 如果A和B不在同一個域名下應該是沒有辦法獲取到的吧,比如我把相關token存在A.com的localstorage里,在進入B.com 的時候 localstorage里是沒有token的呀??????

引用ixx的發言:

JWT 解決的最大問題是跨域,如果你們的業務不涉及跨域完全沒有必要用JWTsession 就夠用了,如果有跨域需要,那么改造Session實現跨域訪問,要比改造JWT實現單用戶登陸復雜的多

扯雞巴蛋,改造Session怎么就復雜了。服務端不用動,客戶端自己添加Cookie就完事了。在Node作為前端服務器,Servlet做后臺服務端的情況下。Node自己解析SetCookie:響應頭,然后發送第二次訪問時,攜帶Cookie:JESSIONID=xxxx請求頭過來不就行了嗎。

防止JWT被篡改關鍵就在最后的簽名:當客戶端拿著JWT來服務器讀取數據時,服務器會對Header和Payload以及秘鑰再進行一次簽名,和客戶端返回的簽名進行比對,如果不一致,就是被篡改了。

Header以及Payload都是Base64URL的編碼,對應著就可以解碼(任何人都可以,因為沒有涉及到加密方式)。因此,重要信息不要放在這里面,比如同時存放用戶名和密碼。

好處我覺得很大啊:第一個,就是服務器的內存中不用和session機制那樣存儲用戶狀態數據了,分不式的我還沒學到,不亂說;第二個,也不用把token存儲在數據庫了,如果存數據庫,每次去數據庫查詢開銷都不小(redis里存的話,和session區別就不大了,都是占用內存)。

另外,突然想到了如何讓賬號只能在一臺設備登錄?我看了各種文章都是登錄的時候,在Redis里來保存JWT,客戶端每次請求接口判斷本次攜帶的JWT是否和Redis里保存的一直,不一致則登錄失效。那如果這樣做,感覺JWT的優勢就沒有了,有沒有其他方法可以解決JWT同時只能有一個賬號在線的問題?

這個是json web token 的翻譯吧

大佬,這篇文我轉載了,轉載到我的公眾號,會標記署名和原文鏈接的,如果有不便,可以發郵件聯系我,我這邊馬上刪除,大家也可以關注一下我的公眾號哦,公眾號名稱:請快點喜歡我。

是如何保證同一個用戶每次生成的token是不一樣的呢?

沒有有【有狀態】 token 和【無狀態】 token 的對比,和相關的應用場景。

jwt的最大有點應該是應用于分布式系統和減輕服務器存儲狀態信息的開銷
不過缺點也很明顯:
1. 服務器無法控制token失效
2. token到期失效后的自動刷新
解決方案:
一 token的到期后失效的問題可以使后臺服務器針對每次請求都刷新過期時間(即使有是服務器集群也沒關系,拿到刷新后的token在前端直接覆蓋就行)。
二 服務器控制token失效這個問題必須在后臺記錄已經頒發的token,但一般這種操作是允許有延遲的并且頻率不是太高,所以并發的問題不是太嚴重。
詳細的解決方案會在我的博客中介紹(正準備寫。。。)https://blog.csdn.net/u010476739/article/details/98757471

其實JWT是可以控制token的失效的

可以通過控制密鑰的方式來實現token的失效

關于jwt 過期的問題。很多人說 可以在服務端記錄 點什么東西來實現。
都這樣做了。那還叫jwt嗎,, 就和 原來的session 本質上沒區別了。
jwt的核心就是 服務端不存東西。
傳統的session。自己實現的話,那一樣可以 服務端只存 sessionid+過期時間
然后數據加密給客戶端。。

A訪問服務器時返回了token,B拿此token訪問是不是能獲取A的權限呢?

引用韓版女裝的發言:

在數據庫里或服務端存儲機構保存用戶等陸狀態,如果登錄狀態發生變化,則重新簽發一個包含登錄狀態碼的JWT給客戶端,原來的A設備因為登錄狀態碼對不上號而被退出,A設備退出后,如果再次登錄時再次重新簽一個包含登錄狀態碼的JWT給客戶端,這樣A手機重新登錄后,B手機因為登錄狀態碼對不上而被退出。

注意下:每次使用登錄功能登錄時登錄時,客戶端向服務端提交登錄數據時,會連同發送重新設定登錄狀態碼的指令,登錄狀態碼為隨機字符串。

這是我的想法,哈俁,大神不要噴,畢竟我是新的人。

完全沒有理解JWT的意義,你這樣表示所有請求全部都要去檢查某個單點數據庫里的所謂“登陸狀態碼”,那等于就是一個session。沒有哪個數據庫吃得消,必須用分布式內存存儲。

cookie是可以跨域的,CSRF正是利用了這一點
這說明瀏覽器自動收發cookie是有利有弊的

有人能解答下下面????這三個問題嗎
受眾(audience) 具體指的是什么(最好舉例說明)?
主題(subject)具體指的是什么(最好舉例說明)?
subject 與 audience 有什么區別?

寫得不錯,比我剛看的另一篇文章好理解些

引用WalkingSun的發言:

簽名可以加時間戳或這其他隨機參與加密,一旦登錄就更新簽名,之前的簽名失效,不會出現多個在線啦

如果簽名里加入了時間戳或者其他隨機參數,那服務器端還得持久化每個用戶的簽名密鑰,也就失去了jwt后端不需要存東西的優點了吧。

如何做到每次請求都會自動延長過期時間。

簡單明了 竟然看懂了

我要發表看法

«-必填

«-必填,不公開

«-我信任你,不會填寫廣告鏈接

极速助手