jsonwebtoken鉴权

加密语法:

jsonwebtoken.sign(payload, secretOrPrivateKey, [options, callback]);

payload 必须是一个object, buffer或者string,用来保存一些信息。
secretOrPrivateKey 是包含HMAC算法的密钥或RSA和ECDSA的PEM编码私钥的string或buffer。
options包括以下选项:

  • itemalgorithm:加密算法(默认值:HS256)
  • expiresIn:以秒表示或描述时间跨度zeit / ms的字符串。如60,“2 days”,“10h”,“7d”, -Expiration time,过期时间
  • notBefore:定义在什么时间之前,该jwt都是不可用的。以秒表示或描述时间跨度zeit / ms的字符串。如:60,“2days”,“10h”,“7d”
  • audience
  • issuer:jwt签发者
  • jwtid: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
  • subject:jwt所面向的用户
  • noTimestamp
  • header

Usage


1. 安装jwt依赖

npm:

npm i jsonwebtoken

yarn:

yarn add jsonwebtoken

2. 生成密钥

# 终端中输入OpenSSl,进入openssl
OpenSSL

OpenSSL>genrsa -out jwt.pem 1024

OpenSSl>rsa -in jwt.pem -pubout -out jwt_pub.pem

会生成两个文件:jwt.pem、jwt_pub.pem

3. 登陆接口生成token

user.js

const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');

const _C = require('./constants');
// ...

Router.post('/login', (req, res) => {
  const { username, pwd } = req.body;
  User.findOne({ username }, (err, doc) => {
    if (err) throw err;
    // 用户不存在
    if (!doc) {
      return res.json(_C.CODE_NO_USER);
    } else {
      // 密码错误
      // # 简化的代码,没有密码加密存储
      if (pwd !== doc.pwd) return res.json(_C.CODE_ERROR_PWD);
      // 验证通过生成 token
      const cert = fs.readFileSync(path.resolve(__dirname, '../lib/jwt.pem'));
      const token = jwt.sign({
        user: doc.username,
        id: doc._id
      }, cert, {
        algorithm: 'RS256',    // 加密算法(默认值:HS256)
        expiresIn: '1h',    // 过期时间
      });
      return res.json({
        ..._C.CODE_SUCCESS,
        data: { token }
      });
    }
  });
});

到这里一个token就已经生成了。

4. 定义解密token的中间件

定义一个校验方法,用来当作中间件,方便使用。
utils.js

const path = require('path');
const jwt = require('jsonwebtoken');

const _C = require('./constants');
// ...

function authtoken (req, res, next) {
  const token = req.cookies.token;
  if (token) {
    const cert = fs.readFileSync(path.resolve(__dirname, './jwt_pub.pem'));
    jwt.verify(token, cert, (err, decoded) =>  {
      // token失效
      if (err) {
        res.json(_C.CODE_PERMISSION_DENIED);
      } else {
      // 放行
        req.userinfo = decoded;
        next();
      }
    });
  // 未登陆
  } else {
    res.json(_C.CODE_NO_LOGIN);
  }
}

5. 在需要的接口中加入token校验

直接在接口的定义中加入中间件即可。
user.js

const _U = require('../lib/utils');
// ...

// get user info
Router.post('/info', _U.authtoken, (req, res) => {
  const userinfo = req.userinfo;
  User.findOne({ username: userinfo.user }, (err, doc) => {
    if (err) throw err;
    if (!doc) {
      return res.json(_C.CODE_NO_USER);
    } else {
      return res.json({
        ..._C.CODE_SUCCESS,
        data: {
          name: doc.username,
          user_id: doc.username,
          access: [doc.type]
        }
      });
    }
  });
});
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值