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
});
中间件
登录成功返回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;
}
注意,验证通过要设置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 }
在需要验证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