Skip to content

JWT在Nodejs中的使用

一、jwt是什么?

Json web token (JWT),是基于Json的一个公开规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息,他的两大使用场景是:认证数据交换

使用原理:

  • 由服务端根据规范生成一个令牌(token),并且发放给客户端。此时客户端请求服务端的时候就可以携带者令牌,以令牌来证明自己的身份信息。

二、JWT的构成

JWT是由三段信息构成的,将这三段信息文本用 . 链接一起就构成了Jwt字符串,例如

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOjYyNywiZXhwIjoxNTcwMDE0ODg1fQ.vPbQh4syxNCzkKXKPSM93LzzLqoJdzPDNeKz8tz9cFM4NzhIOdPrJcH2DG-9-9MCUufCgrAhhGjuo85GKV4bOQ

三部分依次是

  • 标题(header):包含token的类型(这里是jw)和加密算法(通常直接使用 HMAC SHA256)
  • 有效载荷(payload):载荷就是存放有效信息的地方(token传递的内容)
  • 签名(signature):通过密钥将前两者加密得到最终的token

三、jwt使用流程

(一)项目内安装jwt

bash
$ npm install jsonwebtoken --save

(二)jwt生成、校验 Token

1、引入

js
const jwt = require('jsonwebtoken');

2、生成Token,用.sign()方法

js
// 要生成token的主体信息
const payloadContent = { 
    username: "zhangsan", 
    user_id: 123 
}; 
// 这是加密的key(密钥)
const secretOrPrivateKey = "mr.li		"; 
const token = jwt.sign(payloadContent, secretOrPrivateKey, {
  expiresIn: 60 * 60 * 24 // 24小时过期
});

console.log("-----------------Token----------------\n",token);

3、校验token,用.verify()方法

js
// 从body或query或者header中获取 前端传来的 token
const token = req.body.token || req.query.token || req.headers["x-access-token"];

// 这是加密的key(密钥),必须要和生成Token的密钥一至
const secretOrPrivateKey = "mr.li";
jwt.verify(token, secretOrPrivateKey, function(err, decode) {
  if (err) {
    //  时间失效的时候/ 伪造的token
    console.log("------token已过期或无效的token----------\n", err);
  } else {
    console.log("--------token解析结果------\n", decode.msg); // {username: "zhangsan",user_id: 123}
  }
});

4、简单的封装jwt生成校验Token方法

js
const jwt = require('jsonwebtoken');
var tokenHandler = {
  secretOrPrivateKey: "mr.li", //密钥
  createToken(payloadContent, expTime = 60 * 60 * 24) {
    // 生成token
    let token = jwt.sign(payloadContent, this.secretOrPrivateKey, {
      expiresIn: expTime // 不传默认24小时过期
    });
    return token;
  },
  // 校验token
  checkToken(token) {
    return new Promise((resolve, reject) => {
      jwt.verify(token, this.secretOrPrivateKey, function(err, decode) {
        if (err) {
          //  时间失效的时候/ 伪造的token
          console.log("------token已过期或无效的token----------\n", err);
          reject(err);
        } else {
          console.log("--------token解析结果------\n", decode.msg);
          resolve(decode.msg);
        }
      });
    });
  }
};

四、注意事项

1、设置token过期时间

如果你使用expiresInMinutes来设置token的过期时间,很抱歉它会抛出如下异常

js
ValidationError: "expiresInMinutes" is not allowed

请使用expiresIn:以秒为单位或描述的时间跨度字符串表示rauchg / MS。如:60,“2 days”,“10h”,“7d”


  {expiresIn: 60}       // 有效期60秒(没有时间单位以秒为准)
  {expiresIn: "2 days"}   // 有效期 2天 (后缀为时间单位)下面的类似
  ...... 
	 ('1d')      // 86400000
	 ('10h')     // 36000000
	 ('2.5 hrs') // 9000000
	 ('2h')      // 7200000
	 ('1m')      // 60000
	 ('5s')      // 5000
	 ('1y')      // 31557600000

2、verify时返回的err的值

js
    "err": {
    "name": "TokenExpiredError",
    "message": "jwt expired",   //  token过了有效期
    "expiredAt": "2016-11-07T03:31:25.000Z"
  }
js
 "err": {
    "name": "JsonWebTokenError",
    "message": "invalid token"  //  伪造/无效的token
  }

五、参考文章

https://www.jianshu.com/p/576dbf44b2ae 作者:Dearmadman https://baijiahao.baidu.com/s?id=1643676835054018117&wfr=spider&for=pchttps://www.jianshu.com/p/576dbf44b2ae

官方:https://github.com/auth0/node-jsonwebtoken