NodeJS中token生成与认证

  • 导入依赖

    koa、koa-router、basic-auth、jsonwebtoken

    // package.json
    "dependencies": {
        "basic-auth": "^2.0.1",
        "jsonwebtoken": "^8.4.0",
        "koa": "^2.7.0",
        "koa-router": "^7.4.0"
      }
    
  • 生成token

    const jwt = require('jsonwebtoken')
    
    const generateToken = function(uid, scope){
        const secretKey = "abcdefg"; // 生成token时的密钥,不能泄露
        const expiresIn = 60*60; // 生成的token的有效期
        // 生成token
        // 第一个参数是我们要存储到token中的用户信息数据,uid是用户id,scope是用户权限;
        // 第二个参数是加密的密钥;
        // 第三个参数是附带的属性信息,expiresIn是生成的token的有效期
        const token = jwt.sign({
            uid,
            scope
        },secretKey,{
            expiresIn
        })
        return token
    }
    
  • token认证

    • 编写token认证的中间件

      const baseAuth = require("basic-auth");
      const jwt = require("jsonwebtoken");
      
      class Authenticate {
          constructor() {
          }
      
          // auth是属性,不是方法,返回值是一个方法(中间件)
          get auth() {
              // 返回token认证中间件(中间件是一个函数,而不能是对象)
              return async (ctx, next) => {
                  // 注意baseAuth的参数是ctx.req,而不是ctx.request,ctx.req是node.js原生的request对象,而ctx.request是koa对原生request封装后的对象
                  const userToken = baseAuth(ctx.req);
                  if(!userToken || !userToken.name) {
                      // 抛出自定义的异常
                      throw new global.errors.Forbidden("token令牌不能为空");
                  }
                  let decode;
                  try {
                      // 跟生成token时的密钥要保持一直,可以放在配置文件中
                      const secretKey = "abcdefg";
                      // 对token进行解密操作,获取保存到token中的用户信息
                      decode = jwt.verify(userToken.name, secretKey);
                  } catch(error) {
                      if(error.name === "TokenExpiredError") {
                          throw new global.errors.Forbidden("token令牌已过期");
                      }
                      throw new global.errors.Forbidden("token令牌无效");
                  }
                  // 将用户信息保存到ctx中,可以在其他的中间件中获取到
                  ctx.auth = {
                      uid: decode.uid,
                      scope: decode.scope
                  }
                  // 前面必须要加上await,才能保证洋葱模型,如果不调用next(),就不会执行下一个中间件
                  await next();
              }
          }
      }
      
      module.exports = {
          Authenticate
      };
      
    • 使用token认证中间件

      const Router = require("koa-router");
      const {Authenticate} = require("../../../middlewares/authenticate");
      const router = new Router({
          prefix: "/v1/classic" // 路由前缀
      })
      
      // router上可以注册多个中间件,按照注册顺序执行,比如这里注册了两个中间件,第一个参数是路由地址,后面两个参数都是中间件
      router.get("/laster", new Authenticate().auth(第一个中间件), (ctx, next) => {
        ctx.body = ctx.auth;
      }(第二个中间件))
      

      如果第一个中间件(new Authenticate().auth)中认证token没有通过导致抛出了异常,就不会进入到下一个中间件中()

    • 访问:url GET http:localhost:8082/v1/classic/laster

      在PostMan中发送请求,请求方式是GET,Authenrizention的Type选择Base Auth,参数Username填上面生成的token,Password空着不填

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值