基於express框架的Token實現方案


什么是Token?

在計算機身份認證中是令牌(臨時)的意思,在詞法分析中是標記的意思。一般我們所說的的token大多是指用於身份驗證的token

Token的特點

  • 隨機性
  • 不可預測性
  • 時效性
  • 無狀態、可擴展

基於Token的身份驗證方法

  • 客戶端使用用戶名和密碼請求登錄
  • 服務端收到請求,驗證登錄是否成功
  • 驗證成功后,服務端會返回一個Token給客戶端,反之,返回身份驗證失敗的信息
  • 客戶端收到Token后把Token用一種方式(cookie/localstorage/sessionstorage/其他)存儲起來
  • 客戶端每次發起請求時都選哦將Token發給服務端
  • 服務端收到請求后,驗證Token的合法性,合法就返回客戶端所需數據,反之,返回驗證失敗的信息

JWT(Json Web Tokens)

生成Token的解決方案有許多,常用的一種就是 Json Web Tokens .

JWT標准的Tokens由三部分組成

  1. header
  2. payload
  3. signature

中間使用 " . " 分隔開,並且都會使用Base64編碼方式編碼,如下

eyJhbGc6IkpXVCJ9.eyJpc3MiOiJCIsImVzg5NTU0NDUiLCJuYW1lnVlfQ.SwyHTf8AqKYMAJc

header 部分主要是兩部分內容,一個是 Token 的類型,另一個是使用的算法,比如下面類型就是 JWT,使用的算法是 Hash256。

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

payload

Payload 里面是 Token 的具體內容,這些內容里面有一些是標准字段,你也可以添加其它需要的內容。下面是標准字段:

  • iss:Issuer,發行者
  • sub:Subject,主題
  • aud:Audience,觀眾
  • exp:Expiration time,過期時間
  • nbf:Not before
  • iat:Issued at,發行時間
  • jti:JWT ID

比如下面

{
 "iss": "ninghao.net",
 "exp": "1438955445",
 "name": "wanghao",
 "admin": true
}d

signature

JWT 的最后一部分是 Signature ,這部分內容有三個部分,先是拼接 Base64 編碼的 header.payload ,再用不可逆的Hamc加密算法加密,加密時使用一個密鑰,這個密鑰服務端保存,生成signature。

最后組合token,如下

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.
SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

客戶端收到這個 Token 以后把它存儲下來,下回向服務端發送請求的時候就帶着這個 Token 。服務端收到這個 Token ,然后進行驗證,通過以后就會返回給客戶端想要的資源。

Nodejs實現

token.js
var crypto=require("crypto");
var token={
    createToken:function(obj,timeout){
        console.log(parseInt(timeout)||0);
        var obj2={
            data:obj,//payload
            created:parseInt(Date.now()/1000),//token生成的時間的,單位秒
            exp:parseInt(timeout)||10//token有效期
        };

        //payload信息
        var base64Str=Buffer.from(JSON.stringify(obj2),"utf8").toString("base64");

        //添加簽名,防篡改
        var secret="hel.h-five.com";
        var hash=crypto.createHmac('sha256',secret);
            hash.update(base64Str);
        var signature=hash.digest('base64');


        return  base64Str+"."+signature;
    },
    decodeToken:function(token){

        var decArr=token.split(".");
        if(decArr.length<2){
            //token不合法
            return false;
        }

        var payload={};
        //將payload json字符串 解析為對象
        try{
            payload=JSON.parse(Buffer.from(decArr[0],"base64").toString("utf8"));
        }catch(e){
            return false;
        }

        //檢驗簽名
        var secret="hel.h-five.com";        
        var hash=crypto.createHmac('sha256',secret);
            hash.update(decArr[0]);
        var checkSignature=hash.digest('base64');

        return {
            payload:payload,
            signature:decArr[1],
            checkSignature:checkSignature
        }
    },
    checkToken:function(token){
        var resDecode=this.decodeToken(token);
        if(!resDecode){

            return false;
        }

        //是否過期
        var expState=(parseInt(Date.now()/1000)-parseInt(resDecode.payload.created))>parseInt(resDecode.payload.exp)?false:true;
        if(resDecode.signature===resDecode.checkSignature&&expState){

            return true;
        }

        return false;
    }
    
}
module.exports=exports=token;

參考文獻:https://ninghao.net/blog/2834


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM