json web token for Egg.js 實踐

神奇的包子發表於2019-03-04

認識json web token

根據維基百科的定義,JSON WEB TokenJWT,讀作 [/dʒɒt/]),是一種基於JSON的、用於在網路上宣告某種主張的令牌(token)。JWT通常由三部分組成: 頭資訊(header), 訊息體(payload)和簽名(signature)。

頭資訊指定了該JWT使用的簽名演算法:

header = `{"alg":"HS256","typ":"JWT"}`
複製程式碼

訊息體包含了JWT的意圖:

payload = `{"loggedInAs":"admin","iat":1422779638}`
複製程式碼

簽名則通過私有的key計算而成:

key = `secretkey`  
unsignedToken = encodeBase64(header) + `.` + encodeBase64(payload)  
signature = HMAC-SHA256(key, unsignedToken) 
複製程式碼

最後在未簽名的令牌尾部拼接上base64url編碼的簽名(同樣使用”.”分隔)就是JWT了:

token = encodeBase64(header) + `.` + encodeBase64(payload) + `.` + encodeBase64(signature) 
複製程式碼

Egg.js jwt實踐

1.安裝egg-jwt外掛

npm install egg-jwt --save
複製程式碼

2.啟用egg-jwt外掛

// {app_root}/config/plugin.js
exports.jwt = {
  enable: true,
  package: "egg-jwt"
};
複製程式碼

3.配置jwt 私有key

// {app_root}/config/config.default.js
exports.jwt = {
  secret: "123456" //自己設定的值
};
複製程式碼

4.設定路由

// {app_root}/app/router.js      
  router.get(`/`, controller.home.index);
  router.post(`/user`,app.jwt,controller.home.user);
  router.get(`/login`,controller.home.login);
複製程式碼

5.Login方法

onst user = ctx.request.body
    if(user && user.name) {
        let userToken = {
            name: user.name
        }
        const token = app.jwt.sign(userToken, secret, {expiresIn: `1h`})  //token簽名 有效期為1小時
        ctx.body = {
            message: `獲取token成功`,
            code: 1,
            token
        }
    } else {
        ctx.body = {
            message: `引數錯誤`,
            code: -1
        }
    }
	  }
複製程式碼

6.User方法

 const token = ctx.header.authorization  // 獲取jwt
    let payload
    if (token) {
        payload = await app.jwt.verify(token.split(` `)[1], secret)  // // 解密,獲取payload
        ctx.body = {
            payload
        }
    } else {
        ctx.body = {
            message: `token 錯誤`,
            code: -1
        }
    }
複製程式碼

7.通過curl模擬請求

curl http://127.0.0.1:7001/user
//返回Authentication Erro  //驗證錯誤,說明我們的jwt已經生效
複製程式碼

訪問 http://127.0.0.1:7001/login 帶上引數name

curl -d "name=tiptoe" http://127.0.0.1:7001/api/login
//返回結果{"message":"獲取token成功","code":1,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGlwdG9lIiwiaWF0IjoxNDk2Mzg4NzgwLCJleHAiOjE0OTYzOTIzODB9.N2e-84Pmf466DQJ2x3ldd1AWC1IL97ZRWwiDR-Oebhs"}
複製程式碼

然後在header中加入token,在訪問http://127.0.0.1:7001/user

// Authorization: Bearer 授權:令牌型別為Bearer curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGlwdG9lIiwiaWF0IjoxNDk2Mzg4NzgwLCJleHAiOjE0OTYzOTIzODB9.N2e-84Pmf466DQJ2x3ldd1AWC1IL97ZRWwiDR-Oebhs" http://127.0.0.1:7001/user
複製程式碼

返回如下內容,說明認證已經通過

{"payload":{"name":"tiptoe","iat":1496398614,"exp":1496402214}}
複製程式碼

相關文章