下载依赖包
yarn add jsonwebtoken
准备好三个方法,分别创建token、校验token、查询token
/**
* utils/token/addToken.js
* 创建token
*/
const jwt = require('jsonwebtoken');
const config = require('../config/token_config');
exports.addToken = (userInfo) => {
// jwt.sign三个参数:第一个参数是Object,传入想加密的信息,第二个参数是加密的key,自定义;第三个参数是过期时间
const token = jwt.sign({
id: userInfo.id,
user: userInfo.username,
}, config.secret, { expiresIn: '2h' }); // 秒做单位时用数字,其他单位用字符串。如60,"2 days","10h","7d"
return token;
}
/**
* utils/token/verifyToken.js
* 校验token
* 写个接口调用这个方法,校验添加token是否成功(可以跳过)
*/
const jwt = require('jsonwebtoken');
const config = require('../config/token_config');
exports.verifyToken = (token) => {
const verifyResult = jwt.verify(token, config.secret, (err, decoded) => {
// 如果token过期,会获取err,如果未过期,会获取decoded(被加密的内容)
if (err) {
return false;
} else {
// console.log(decoded);
return true;
}
});
return verifyResult
}
/**
* utils/token/checkToken.js
* 写一个中间件查询token是否有效
*/
const { verifyToken } = require('./verifyToken');
const config = require('../config/token_config');
async function checkToken (ctx, next) {
let url = ctx.request.url;
// 登录、静态文件 不用校验
// 静态文件如果要校验,会导致首页打开校验不通过,不知道有没有好的办法规避掉
if (url === "/login" || url === "/" || url.indexOf('.') >=0) await next();
else {
let token = ctx.request.headers["access_token"];
// 解码
let isNotExpire = await verifyToken(token, config.secret);
if (isNotExpire) {
// 未过期
await next();
} else {
//过期
ctx.body = {
code: 401,
msg: 'token 已过期,请重新登录',
data: ''
};
}
}
}
module.exports = checkToken
调用checkToken中间件
/**
* app.js
*/
... // 省略其他代码
app.use(checkToken); // 要写在route前面
... // 省略其他代码
登录请求创建token
/**
* /routes/user.js
*/
const router = require('koa-router')();
const { addToken } = require('../utils/token/addToken');
router.post('/login', async (ctx, next) => {
try {
const { username, password } = ctx.request.body;
let res = await query(USER_LOGIN(username, password));
let result = {};
if (res.length) {
delete res[0].password;
// 生成token并存入user表
let token = addToken({ id: res[0].id, username: res[0].username }); // token中要携带的信息,自己定义
await query(UPDATE_TOKEN(res[0].id, token)); // 把token存入user表当前用户的token字段
result = {
code: 200,
data: {
...res[0],
token,
}
};
} else {
result = {
code: 401,
msg: '登录用户不存在或密码输入错误',
data: []
}
}
ctx.body = result;
} catch (e) {
console.log(e);
}
});