JWT is a stateless token, which does not require us to save the token in Redis. It supports custom parameters to generate the token, and then the client side sends it to us to analyze and verify the token with the corresponding parameters. However, the disadvantage is that it is not possible to achieve single sign-on in this way, so choose according to your business needs.

Install: NPM I jsonWebToken –save

const jwt = require('jsonwebtoken');
const config = require('.. /config/config'); /** * Generate JWT token * @param {*} uid * @param {*} scope */ const generateToken =function(uid,scope){
    const key = config.tokenKey.key;
    const expiresIn = config.tokenKey.expiresIn;
    const token = jwt.sign({uid,scope},key,{expiresIn:expiresIn});
    return token
}

module.exports = {
    generateToken
}Copy the code

Let’s create a new tool file to hold our method:



JWT uses the sign method to generate arguments. The first argument allows us to pass in a js object: user ID and scope. Scope is a specified number 2. As a key, the third parameter is to set our expiration time,

I wrote the key and expiration date in the configuration file

const config = {
    db:{
        database:'* *',
        host:'* *',
        port:3306,
        user:'root',
        password:'* *'
    },
    redis:{
        port:6379,
        host:'127.0.0.1'
    },
    tokenKey:{
        key:'* *'Exportresin :60*60*24 // test environment so set longer}} module.exports = configCopy the code

How to Verify the Token

const jwt = require('jsonwebtoken');
const config = require('.. /config/config');

class Auth{
    constructor(level){
        this.level = level || 0;
    }
    get w() {return async (ctx,next)=>{
            let token = ctx.request.header.token;
            let userId = ctx.request.header.uid;
            if(! token || ! userId){ throw new global.err.HttpException(500,'Missing user identity information', 403); } try { var becode = jwt.verify(token,config.tokenKey.key) } catch (error) { console.log(error)if(error.name == 'TokenExpiredError'){
                    throw new global.err.HttpException(500,'Token has expired, please log in again',403)
                }
                throw new global.err.HttpException(500,'Token is not legal',403)} // Verify that the token and ID matchif(becode.uid ! = userId){ throw new global.err.HttpException(500,'User ID and Token do not match',403)} // Verify permission levelif(becode.scope < this.level){
                throw new global.err.HttpException(500,'Insufficient permissions'Ctx. auth = {uid:becode.uid, scope:becode.scope} await next(); } } } module.exports = {Auth}Copy the code

API Permission Classification

Here I create an Auth class to validate the token in middleware form

When we generate tokens with JWT, we pass in a scope parameter that we use to do API privilege classification

The generateToken method is the method we used to generate the token with the userType passed in

Then compare this.level with becode.scope

let token = generateToken(user.id,user.userType)Copy the code

Note that the middleware must write next() when it is finished or the rest of the code cannot proceed

The next step is to use this class where we need to validate the API

New Auth(2).w will not be able to access the current API if the scope in the user token is userType<2



/** * obtain user information based on userId * userId */ router.get('/userInfo',new Auth().w, async (ctx, next) => {
  if(! ctx.query.userId){ throw new global.err.HttpException(500,'Missing arguments',500)
  }
  let data = await User.findOne({
    where: { id: ctx.query.userId },
    attributes:{exclude:['registerTime'.'password']}
  })
  ctx.body = {
    code: 200,
    data: data
  }
})Copy the code

Note that we need to instantiate our class new Auth().w in front of the middleware. W is a property, not a method. Note that parentheses are not used