koa2:jwt生成token与验证token

jsonwebtoken:生成token
默认加密方式: (HMAC SHA256)
生成: jwt.sign(payload, secretOrPrivateKey, [options, callback])

// 实例
cosnt priCert = 'A SECRET';
const token = jwt.sign({
    	exp: Math.floor(Date.now() / 1000) + (30 * 60), // 过期时间
        data: 'createToken'  // payload: 如果设置了过期时间必须是Object(exp or any other claim is only set if the payload is an object literal. Buffer or string payloads are not checked for JSON validity.)
    }, priCert);
 

验证:jwt.verify(token, secretOrPublicKey, [options, callback])

jwt.verify(token,priCert, (err, decoded) => {
  // err
  if(decoded){
  		console.log(decoded)// 'createToken'
  	}// decoded undefined
});

1 登录页面

  • 中间件

    • 路由:koa-router
    • token生成:jsonwebtoken
    • nodejs加密:crypto
  • 登录成功返回token

const router = require('koa-router')();
const { manageUser } = require('../models/manageUserModel');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const fs = require('fs')

router.prefix('/manage');
router.post('/login', async (ctx, next) => {
    // 创建用户
  /*
          let user = createUser('tzgManage', 'tzgManage')
        await user.save((err, doc) => {
            console.log(doc);
            if (err) {
                console.log(err)
            }
        });
  */  

    
    // 获取登录信息
    const userMsg = ctx.request.body;
    // 判断是否为空
    if (userMsg) {
        // 对密码进行同样的加密
        const name = userMsg.name;
        const password = encrytoPwd(userMsg.password);
        // 检查用户名密码
        const result = await manageUser.findOne({ name: name, password: password });
        if (result) {
            // 生成token
            const token = generateToken();
            try {
                // 将新生成的token存入数据库
                await manageUser.updateOne({ name: name },{$set: { token: token }});
                // 登录成功,返回token
                ctx.status = 200;
                ctx.body = {
                    'result': 'success',
                    'token': token
                }
            } catch (error) {
                // 无法返回token,返回错误信息
                ctx.status = 401;
                ctx.body = {
                    'error': {
                        'type': "ERROR",
                        'message': error
                    }
                }
            }

        } else {
            // 信息有误,登录失败
            ctx.status = 400;
            ctx.body = {
                'error': {
                    'type': "LOGIN_FAILED!",
                    'message': '账号或密码错误!'
                }
            }
        }

    }
});


module.exports = router;
// 读取私钥
const priCert = fs.readFileSync('./rsa_private_key.pem');
// 生成token
function generateToken() {
    const created = Math.floor(Date.now() / 1000) + (30 * 60);
    const token = jwt.sign({
        data: 'createToken'
    }, priCert);
    return token;
}

// 对密码加密
function encrytoPwd(pwd) {
    const hmac = crypto.createHmac('sha256', 'a secret');
    hmac.update(pwd);
    return hmac.digest('hex');
}

// 创建用户
function createUser(name, password) {
    // 加密密码
    const encrytoPassword = encrytoPwd(password);
    const user = new manageUser({
        name: name,
        password: encrytoPassword,
    });
    return user;
}

2 验证中间件

注意,验证通过要设置status=200,否则无法返回正确数据

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

const priCert = fs.readFileSync('./rsa_private_key.pem');

async function verifyToken(ctx, next) {
    const dataString = ctx.header.authorization;
    try {
        const dataArr = dataString.split(' ');
        const token = dataArr[1];
    
        let playload = await jwt.verify(token, priCert)
        const { data } = playload;
        if (data === 'createToken') {
            ctx.status = 200 //这里非常重要,只有设置了status,koa-router才识别请求正确继续进入路由
            await next()
        }

    } catch (error) {
        ctx.body = {
            "error": {
                "type": "LOGIN_FAILED",
                "message": "未知",
            }

        }
    }
}
        module.exports = { verifyToken }

3 引入验证中间件

在需要验证token的页面引入验证中间件,使用router.use(verifyToken)

const router = require('koa-router')();
const { statistic } = require('../models/statisticModel');
const { verifyToken } = require('../middleware/verify')

router.use(verifyToken)
router.prefix('/manage'); 
router.get('/statistics', async (ctx, next) => {
	//.....业务代码
})


module.exports = router

你可能感兴趣的:(NodeJs)