下载依赖包
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); }});