下载依赖包

  1. yarn add jsonwebtoken

准备好三个方法,分别创建token、校验token、查询token

  1. /**
  2. * utils/token/addToken.js
  3. * 创建token
  4. */
  5. const jwt = require('jsonwebtoken');
  6. const config = require('../config/token_config');
  7. exports.addToken = (userInfo) => {
  8. // jwt.sign三个参数:第一个参数是Object,传入想加密的信息,第二个参数是加密的key,自定义;第三个参数是过期时间
  9. const token = jwt.sign({
  10. id: userInfo.id,
  11. user: userInfo.username,
  12. }, config.secret, { expiresIn: '2h' }); // 秒做单位时用数字,其他单位用字符串。如60,"2 days","10h","7d"
  13. return token;
  14. }
  1. /**
  2. * utils/token/verifyToken.js
  3. * 校验token
  4. * 写个接口调用这个方法,校验添加token是否成功(可以跳过)
  5. */
  6. const jwt = require('jsonwebtoken');
  7. const config = require('../config/token_config');
  8. exports.verifyToken = (token) => {
  9. const verifyResult = jwt.verify(token, config.secret, (err, decoded) => {
  10. // 如果token过期,会获取err,如果未过期,会获取decoded(被加密的内容)
  11. if (err) {
  12. return false;
  13. } else {
  14. // console.log(decoded);
  15. return true;
  16. }
  17. });
  18. return verifyResult
  19. }
  1. /**
  2. * utils/token/checkToken.js
  3. * 写一个中间件查询token是否有效
  4. */
  5. const { verifyToken } = require('./verifyToken');
  6. const config = require('../config/token_config');
  7. async function checkToken (ctx, next) {
  8. let url = ctx.request.url;
  9. // 登录、静态文件 不用校验
  10. // 静态文件如果要校验,会导致首页打开校验不通过,不知道有没有好的办法规避掉
  11. if (url === "/login" || url === "/" || url.indexOf('.') >=0) await next();
  12. else {
  13. let token = ctx.request.headers["access_token"];
  14. // 解码
  15. let isNotExpire = await verifyToken(token, config.secret);
  16. if (isNotExpire) {
  17. // 未过期
  18. await next();
  19. } else {
  20. //过期
  21. ctx.body = {
  22. code: 401,
  23. msg: 'token 已过期,请重新登录',
  24. data: ''
  25. };
  26. }
  27. }
  28. }
  29. module.exports = checkToken

调用checkToken中间件

  1. /**
  2. * app.js
  3. */
  4. ... // 省略其他代码
  5. app.use(checkToken); // 要写在route前面
  6. ... // 省略其他代码

登录请求创建token

  1. /**
  2. * /routes/user.js
  3. */
  4. const router = require('koa-router')();
  5. const { addToken } = require('../utils/token/addToken');
  6. router.post('/login', async (ctx, next) => {
  7. try {
  8. const { username, password } = ctx.request.body;
  9. let res = await query(USER_LOGIN(username, password));
  10. let result = {};
  11. if (res.length) {
  12. delete res[0].password;
  13. // 生成token并存入user表
  14. let token = addToken({ id: res[0].id, username: res[0].username }); // token中要携带的信息,自己定义
  15. await query(UPDATE_TOKEN(res[0].id, token)); // 把token存入user表当前用户的token字段
  16. result = {
  17. code: 200,
  18. data: {
  19. ...res[0],
  20. token,
  21. }
  22. };
  23. } else {
  24. result = {
  25. code: 401,
  26. msg: '登录用户不存在或密码输入错误',
  27. data: []
  28. }
  29. }
  30. ctx.body = result;
  31. } catch (e) {
  32. console.log(e);
  33. }
  34. });