koa如何进生成token和对token进行校验

山水有轻音 2021-05-24 AM 350℃ 0条

一、安装包文件

npm install jsonwebtoken --save

二、通过jsonwebtoken可以创建token

const jwt = require('jsonwebtoken')
    // 创建token
let token = jwt.sign(obj,secret,opt)
    //解码token
let payload = jwt.verify(token,secret)

实现思路

login处理

当我们收到前台传来的帐号密码查库比对通过后,创建token并返回客户端

const police = require("../../../model/police");
    const jwt = require('jsonwebtoken')
     
    let myPolice = new police(); 
    let {secret} =  require('../../../util/secret.js')
     
    async function login(ctx, next) {
      let postData = ctx.request.body
      let selectResult = await myPolice.checkLogin(postData)
      if (selectResult.err) {
        ctx.body = {
          status: 1,
          message: err
        }
      } else if (!selectResult.result) {
        ctx.body = {
          status: 1,
          message: '用户不存在'
        }
      } else if (selectResult.result[0].password !== postData.password) {
        ctx.body = {
          status: 1,
          message: '密码错误'
        }
      } else {
        // 帐号密码正确  创建token   
        //payload中写入一些值  time:创建日期  timeout:多长时间后过期
        let payload = {userNumber:postData.userNumber,time:new Date().getTime(),timeout:1000*60*60*2}
        let token = jwt.sign(payload, secret);
        ctx.body = {
          status: 0,
          message: '登录成功',
          data:{
            token
          }
        }
      }
    }
     
    module.exports = login

Payload参数说明

iss: 签发者
sub: 面向用户
aud: 接收者
iat(issued at): 签发时间
exp(expires): 过期时间
nbf(not before):不能被接收处理时间,在此之前不能被接收处理
jti:JWT ID为web token提供唯一标识

例如
{"sub":"subject","aud":"sina.com","iss":"baidu.com","iat":1528360628,"nbf":1528360631,"jti":"253e6s5e","exp":1528360637}

jwt.sign(object,key)说明

两个参数分别是签名算法和自定义的签名Key(盐)。签名key可以byte[] 、String及Key的形式传入。前两种形式均存入builder的keyBytes属性,后一种形式存入builder的key属性。如果是第二种(及String类型)的key,则将其进行base64解码获得byte[] 。

三、如何进行token校验

1、创建checkToken.js文件的中间件

1、token解密方法一

const jwt = require('jsonwebtoken')
    async function check(ctx, next) {

        let url = ctx.url.split('?')[0]
        
        // 如果是登陆页面和注册页面就不需要验证token了
        if (url === '/admin/user/login' || url === '/admin/user/register') {
            await next()
        } else {
    
            // 否则获取到token
            let token = ctx.request.headers["authorization"]
    
            if (token) {
    
                // 如果有token的话就开始解析
                const tokenItem = jwt.verify(token, 'token')
                // 将token的创建的时间和过期时间结构出来
                const { time, timeout } = tokenItem
                // 拿到当前的时间
                let data = new Date().getTime();
                // 判断一下如果当前时间减去token创建时间小于或者等于token过期时间,说明还没有过期,否则过期
                if (data - time <= timeout) {
                    // token没有过期
                    await next()
                } else {
                    ctx.body = {
                        status: 405,
                        message:'token 已过期,请重新登陆'
                    }  
                }
            }
        }
    }

    module.exports = checkToken

2、token解密方法二

    const Promise = require("bluebird");
    const jwt = require("jsonwebtoken");
    const verify = Promise.promisify(jwt.verify);
    let { secret } = require("../util/secret");
     
    async function check(ctx, next) {
      let url = ctx.request.url;
      // 登录 不用检查
      if (url == "/users/login") await next();
      else {
          // 规定token写在header 的 'autohrization' 
        let token = ctx.request.headers["authorization"];
        // 解码
        let payload = await verify(token,secret);
        let { time, timeout } = payload;
        let data = new Date().getTime();
        if (data - time <= timeout) {
            // 未过期
          await next();
        } else {
            //过期
          ctx.body = {
            status: 50014,
            message:'token 已过期'
          };
        }
      }
    }
     
    module.exports = check

四、在app.js入口中注册使用

const checkToken = require('./middleware/checkToken.js')
    
// 验证token的中间件函数
    
app.use(checkToken)
标签: koa, Token

非特殊说明,本博所有文章均为博主原创。

评论啦~