使用NodeJS實現JWT原理

2021-10-09 14:26:32 字數 4048 閱讀 1765

jwt是json web token的簡稱,本文介紹它的原理,最後後端用nodejs自己實現如何為客戶端生成令牌token和校驗token

我們用nodejs為前端或者其他服務提供resful介面時,http協議他是乙個無狀態的協議,有時候我們需要根據這個請求的上下獲取具體的使用者是否有許可權,針對使用者的上下文進行操作。所以出現了cookies session還有jwt這幾種技術的出現, 都是對http協議的乙個補充。使得我們可以用http協議+狀態管理構建乙個的面向使用者的web應用。

session和cookies是有聯絡的,session就是服務端在客戶端cookies種下的session_id, 服務端儲存session_id所對應的當前使用者所有的狀態資訊。每次客戶端請求服務端都帶上cookies中的session_id, 服務端判斷是否有具體的使用者資訊,如果沒有就去調整登入。

jwt是json web token的全稱,他解決了session以上的問題,優點是伺服器不儲存任何會話資料,即伺服器變為無狀態,使其更容易擴充套件,什麼情況下使用jwt比較合適,我覺得就是授權這個場景,因為jwt使用起來輕便,開銷小,後端無狀態,所以使用比較廣泛。

jwt 的原理是,伺服器認證以後,生成乙個 json 物件,發回給使用者,就像下面這樣。

以後,使用者與服務端通訊的時候,都要發回這個 json 物件。伺服器完全只靠這個物件認定使用者身份。為了防止使用者篡改資料,伺服器在生成這個物件的時候,會加上簽名。

流程說明:

1.瀏覽器發起請求登陸,攜帶使用者名稱和密碼;

2.服務端根據使用者名稱和明碼到資料庫驗證身份,根據演算法,將使用者識別符號打包生成 token

3.伺服器返回jwt資訊給瀏覽器,jwt不應該包含敏感資訊,這是很重要的一點

4.瀏覽器發起請求獲取使用者資料,把剛剛拿到的 token一起傳送給伺服器,一般放在header裡面,欄位為authorization

5.伺服器發現資料中有 token,decode token的資訊,然後再次簽名,驗明正身;

6.伺服器返回該使用者的使用者資料;

7.伺服器可以在payload設定過期時間, 如果過期了,可以讓客戶端重新發起驗證。

jwt包含了使用.風格的三個部分

// algorithm => hmac sha256

// type => jwt

這是固定的寫法,alg表面要用的是hs256演算法

iss

(issuer):簽發人

exp(expiration time):過期時間

sub(subject):主題

aud(audience):受眾

nbf(not before):生效時間

iat(issued at):簽發時間

jti(

jwtid

):編號

除了這七個,可以自定義,比如過期時間

對前兩部分header和payload進行簽名,防止資料篡改

hmacsha256

(base64urlencode

(header)

+"."

+base64urlencode

(payload)

, secret)

secret是一段字串,後端儲存,需要注意的是jwt 作為乙個令牌(token),有些場合可能會放到 url(比如 api.example.com/?token=***)。base64 有三個字元+、/和=,在 url 裡面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 base64url 演算法。

http 請求的頭資訊authorization字段裡面,bearer也是規定好的

authorization: bearer 
通過url傳輸(不推薦)

如果是post請求也可以放在請求體中

可以使用現成庫,jwt-******或者jsonwebtoken

let koa =

require

('koa');

let router =

require

('koa-router');

let bodyparser =

require

('koa-bodyparser');

let jwt =

require

('jwt-******');

let router =

newrouter()

newkoa()

;use

(bodyparser()

);// 可以自己自定義

let secret =

'zhenglei'

;// 驗證是否登陸

router.

post

('/login'

,async

(ctx)

=>

= ctx.request.body;

if(username ===

'admin'

&& password ===

'admin')}

});// 驗證是否有許可權

router.

get(

'/validate'

,async

(ctx)

=>

}catch

(e)}

}else}}

);use(router.

routes()

);listen

(4000

);

1.實現兩個介面 乙個是/login驗證是否登入,乙個是validate,驗證是否有許可權

2.請求login介面的時候,客戶端帶username和password, 後端一般會查資料庫,驗證是否存在當前使用者,如果存在則為username進行簽名,千萬不要給password這些敏感資訊也帶進來簽名

3.客戶端接收後端給的token令牌,再請求其他介面,比如這個例子的/validate的時候,ajax請求的時候,可以在header指定authorization字段,後端拿到token進行decode,然後將header和payload進行再一次的簽名,如果前後的簽名一致,說明沒有被篡改過,則許可權驗證通過。因為是同步的過程,所以可以用try catch來捕捉錯誤

1.sha256雜湊演算法,可以用nodejs的內建加密模組crypto, 生成base64字串,要注意的是生成base64需要為+ - = 做一下替換,=被省略、+替換成-,/替換成_ 。這就是 base64url 演算法。

2.token令牌的組成是header, payload和sigin的通過.來組成

3.base64urlunescape的解碼是固定寫法,decode出base64的內容

let myjwt =

,base64urlescape

(str)

,tobase64

(content)

,encode

(username, secret));

let content =

this

.tobase64

(username)

;let sign =

this

.sign

([header,content]

.join

('.'

),secret)

;return

[header,content,sign]

.join

('.')}

,base64urlunescape

(str)

,decode

(token, secret)

else

}}

jwt原理及使用

jwt json web token 在後台認證時使用 1 不需要後台儲存session資訊,僅占用一點計算資源 2 後端接入伺服器平行擴充套件時,不用考慮認證的平行擴充套件問題 jwt由三部分組成 頭,資訊體,簽名。頭 描述加密演算法和令牌型別 jwt 資訊體 是json欄位,jwt定義了幾個通用...

JWT基本原理及其在nodeJS中的使用

基於傳統的token認證與jwt的比較 基於傳統的token認證 使用者登入,服務端返回token儲存在服務端,以後使用者再來訪問時,需要攜帶token,服務端獲取token後再去資料庫中獲取進行校驗 jwt 使用者登入,服務端給使用者返回乙個token 服務端不儲存 以後使用者再來訪問,需要攜帶t...

jwt原理及簡單實現

文章2 編碼 乙個token是一串base64字元,大概分成head payload sign三部分,這三部分以.分割。其中head記錄的是加密演算法,payload記錄的是你定義的一些資訊,sign則是head base64字元 payload base64字元 秘鑰的加密base64字元。解碼 ...