真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

nodejs中如何使用JWT

這篇“nodejs中如何使用JWT”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“nodejs中如何使用JWT”文章吧。

10年積累的成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有多倫免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

什么是JWT

JWT也就是JSON Web Token的縮寫,也就是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境中一種認證解決方案,在傳統(tǒng)的認證機制中,無非是一下幾個步驟:

1. 用戶將賬號密碼發(fā)送到服務(wù)器;

2. 服務(wù)器通過驗證賬號密碼后,會在當前session中保存一些用戶相關(guān)的信息,用戶角色或者過期時間等等;

3. 服務(wù)器給用戶一個session_id, 寫入用戶的Cookie或者客戶端自行保存在本地;

4. 用戶每次請求服務(wù),都需要帶上這個session_id,或許會通過Cookie,或者其他的方式;

5. 服務(wù)器接收到后,回去數(shù)據(jù)庫查詢當前的session_id,校驗該用戶是否有權(quán)限;

這種模式有一種優(yōu)勢在于,服務(wù)器隨時可以終止用戶的權(quán)限,可以去數(shù)據(jù)庫修改或者刪除當前用戶的session信息。但是也有一點不好的,就是如果是服務(wù)器集群的話,所有的機器就需要共享這些session信息,確保每臺服務(wù)器都能夠獲取到相同的session存儲信息。雖然可以解決這些問題,但是工程量巨大。

JWT方案的優(yōu)勢呢,就是不保存這些信息,token數(shù)據(jù)保存在客戶端,每次接受請求時,只需要校驗就好。

JWT的原理

簡單說一下JWT的原理,其實就是客戶端發(fā)送請求認證的時候,服務(wù)器在認證用戶之后,會生成一個JSON對象,大概包括“你是誰,你是干嘛的等等,到期時間”這些信息,重要的是一定要有到期時間;大致格式為:

{
    username: "賊煩字符串er",
    role: "世代碼農(nóng)",
    endTime: "2022年5月20日"
}

但是不會用這么膚淺的方式傳給你,它會通過制定的簽名算法和你提交的payload的一些信息進行可逆的簽名算法進行簽名后傳輸,大致的格式我用一張圖片表示:

nodejs中如何使用JWT

由圖片可以看出,返回的信息大致分為三部分,左側(cè)為簽名之后的結(jié)果,也就是返回給客戶端的結(jié)果,右側(cè)也是就Decoded的源碼了,三部分由“點”隔開,分別由紅、紫、青三種顏色一一對應(yīng):

  • 第一個紅色部分是Header,Header中主要是指定了的方式,圖中的簽名算法(默認HS256)就是帶有 SHA-256 的 HMAC 是一種對稱算法, 雙方之間僅共享一個密鑰,typ字段標識為JWT類型;

  • 第二個紫色部分payload,就是一個JSON對象,也就是實際要傳輸?shù)臄?shù)據(jù),官方有七個字段可以使用:

    • iss (issuer):簽發(fā)人

    • exp (expiration time):過期時間

    • sub (subject):主題

    • aud (audience):受眾

    • nbf (Not Before):生效時間

    • iat (Issued At):簽發(fā)時間

    • jti (JWT ID):編號

除了這些字段,你還可以搞一些自定義的字段,由于JWT默認是不加密的,所以在使用的時候盡量注意不要使用一些敏感數(shù)據(jù)。

  • 第三部分就是Signature簽名,這一部分,是由你自己指定且只有服務(wù)器存在的秘鑰,然后使用頭部指定的算法通過下面的簽名方法進行簽名。

JWT的簡單使用

下面我們來感受一下具體的使用:

第一步:我們需要搭建一個node的項目;通過npm init -y初始化一個項目;之后我們需要安裝依賴,分別按狀express、jsonwebtokennodemon三個依賴:

$ npm i express jsonwebtoken nodemon

之后在package.json中的scripts字段中添加nodemon app.js命令:

"scripts": {
    "start": "nodemon app.js"
},

第二步:初始化一下node應(yīng)用,在根目錄下創(chuàng)建app.js文件;

// app.js

const express = require("express");
const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log(3000 + " listening..."); // 監(jiān)聽3000端口
});

第三步:引入jsonwebtoken依賴,并且創(chuàng)建接口和服務(wù)器的私鑰;

// app.js

//...
const jwt = require("jsonwebtoken");

const jwtKey = "~!@#$%^&*()+,";
// ...

這里面的jwtKey是我們自定義保存僅限保存在服務(wù)器中的私鑰,之后我們開始寫一個 /login 接口,用來登錄,并且創(chuàng)建本地的模擬數(shù)據(jù)庫用來校驗,并通過jwt.sign方法進行校驗簽名:

// app.js
const database = {
  username: "username",
  password: "password",
};

app.post("/login", (req, res) => {
  const { username, password } = req.body;
  if (username === database.username && password === database.password) {
    jwt.sign(
      {
        username,
      },
      jwtKey,
      {
        expiresIn: "30S",
      },
      (_, token) => {
        res.json({
          username,
          message: "登陸成功",
          token,
        });
      }
    );
  }
});

上面代碼中我們創(chuàng)建了database變量來模擬創(chuàng)建了本地的賬號密碼數(shù)據(jù)庫,用來校驗登陸;接下來建立了一個/loginpost接口,在校驗賬號密碼完全匹配之后,我們通過jsonwebtoken包導(dǎo)入的jwt對象下的人sign方法進行簽名,這個方法有三種接口簽名:

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options?: SignOptions,
): string;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    callback: SignCallback,
): void;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options: SignOptions,
    callback: SignCallback,
): void;

這里用到了函數(shù)重載的方式實現(xiàn)接口,我們這里將實現(xiàn)最后一個接口簽名,第一個參數(shù)可以是一個自定義的對象類型,也可以是一個Buffer類型,還可以直接是一個string類型,我們的源碼使用了object類型,自定義了一些字段,因為jwt在進行簽名是也會對這些數(shù)據(jù)一并進行簽名,但是值得注意的是,這里盡量不要使用敏感數(shù)據(jù),因為JWT默認是不加密的,它的核心就是簽名,保證數(shù)據(jù)未被篡改,而檢查簽名的過程就叫做驗證

當然你也可以對原始Token進行加密后傳輸;

第二個參數(shù):是我們保存在服務(wù)器用來簽名的秘鑰,通常在客戶端-服務(wù)端模式中,JWS 使用 JWA 提供的 HS256 算法加上一個密鑰即可,這種方式嚴格依賴密鑰,但在分布式場景,可能多個服務(wù)都需要驗證JWT,若要在每個服務(wù)里面都保存密鑰,那么安全性將會大打折扣,要知道,密鑰一旦泄露,任何人都可以隨意偽造JWT。

第三個參數(shù):是簽名的選項SignOptions,接口的簽名:

export interface SignOptions {
    algorithm?: Algorithm | undefined;
    keyid?: string | undefined;
    expiresIn?: string | number | undefined;
    /** expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms.js).  Eg: 60, "2 days", "10h", "7d" */
    notBefore?: string | number | undefined;
    audience?: string | string[] | undefined;
    subject?: string | undefined;
    issuer?: string | undefined;
    jwtid?: string | undefined;
    mutatePayload?: boolean | undefined;
    noTimestamp?: boolean | undefined;
    header?: JwtHeader | undefined;
    encoding?: string | undefined;
}

這里我們用的是expiresIn字段,指定了時效時間,使用方法參考這個文檔;

第四個參數(shù)是一個回調(diào),回調(diào)的第二個參數(shù)就是我們通過簽名生成的token,最后將這個token返回給前端,以便存儲到前端本地每次請求是帶上到服務(wù)端進行驗證。

接下來,我們來驗證一下這個接口: 我是在vscode安裝的REST Client插件,之后在根目錄創(chuàng)建一個request.http的文件,文件內(nèi)寫上請求的信息:

POST http://localhost:3000/login
content-type: application/json

{
  "username": "username",
  "password": "password"
}

之后在命令行執(zhí)行npm run start命令啟動服務(wù),之后在requset.http文件上方點擊Send Request按鈕,發(fā)送請求:

nodejs中如何使用JWT

請求成功后,會看到這樣的響應(yīng)報文:

nodejs中如何使用JWT

token字段就是我們JWT生成的token;

下面來驗證一下這個token是否有效,我們在寫一個登錄過后的接口:

app.get("/afterlogin", (req, res) => {
  const { headers } = req;
  
  const token = headers["authorization"].split(" ")[1];
  // 將token放在header的authorization字段中
  jwt.verify(token, jwtKey, (err, payload) => {
    if (err) return res.sendStatus(403);
    res.json({ message: "認證成功", payload });
  });
});

這段代碼中,通過獲取請求頭中的authorization字段中的token進行獲取之前通過JWT生成的token。 之后通過調(diào)用jwt.verify校驗方法校驗這個token是否有效,這個方法分別有三個參數(shù):

// 有四個接口簽名,可以自行查文檔

export function verify(
    token: string,
    // 需要檢驗的token
    secretOrPublicKey: Secret | GetPublicKeyOrSecret,
    // 定義在服務(wù)器的簽名秘鑰
    callback?: VerifyCallback,
    // 獲取校驗信息結(jié)果的回調(diào)
): void;

接下來我們把剛才響應(yīng)的token復(fù)制到請求頭中:

###
GET http://localhost:3000/afterlogin
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwiaWF0IjoxNjUyNzg5NzA3LCJleHAiOjE2NTI3ODk3Mzd9.s9fk3YLhxTUcpUgCfIK4xQN58Hk_XEP5y9GM9A8jBbY

前面的Bearer認證, 是http協(xié)議中的標準認證方式

同樣點擊Send Request當看到下面圖片的響應(yīng),就意味著響應(yīng)成功:

nodejs中如何使用JWT

其實以上就是JWT的一些簡單的用法,接下來再說一下JWT本身存在的優(yōu)缺點.

JWT的不足

  • JWT占用的存儲空間其實并不小,如果我們需要簽名做過多的信息,那么token很可能會超出cookie的長度限制,例如對比一下這兩張圖片:

nodejs中如何使用JWT

很明顯,隨著payload的信息量增大,token的長度也會增加;

  • 安全性,其實如果token的占用空間過大,Cookie最大存儲空間只有4kb前端可以存儲在localStorage之類的本地存儲,但是會帶來一個問題,如果不是放在cookie的話,安全性就會大打折扣,就會有通過js腳本獲取到的風險,就意味著任何hacker都可以拿著它做任何事情;

  • 不靈活的時效性,其實JWT的某方面意義在于用戶token不需要持久化存儲,而是采用服務(wù)器校驗的方式對token進行有效校驗,剛才看到了,簽名也是把到期時間一并簽名的,如果改變到期時間token就會被篡改,由于沒有存儲和手動更改時效的方法,所以很難立刻將這個token刪掉,如果用戶重復(fù)登陸兩次,生成兩個token,那么原則上兩個token都是有效的;

以上就是關(guān)于“nodejs中如何使用JWT”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


當前文章:nodejs中如何使用JWT
分享路徑:http://weahome.cn/article/pipjoj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部