koa+jwt实现token验证与刷新功能


Posted in Javascript onMay 30, 2019

JWT

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

本文只讲Koa2 + jwt的使用,不了解JWT的话请到这里)进行了解。

koa环境

要使用koa2+jwt需要先有个koa的空环境,搭环境比较麻烦,我直接使用koa起手式,这是我使用koa+typescript搭建的空环境,如果你也经常用koa写写小demo,可以点个star,方便~

安装koa-jwt

koa-jwt主要作用是控制哪些路由需要jwt验证,哪些接口不需要验证:

import * as koaJwt from 'koa-jwt';
//路由权限控制 除了path里的路径不需要验证token 其他都要
app.use(
  koaJwt({
    secret: secret.sign
  }).unless({
    path: [/^\/login/, /^\/register/]
  })
);

上面代码中,除了登录、注册接口不需要jwt验证,其他请求都需要。

使用jsonwebtoken生成、验证token

执行npm install jsonwebtoken安装jsonwebtoken

相关代码:

import * as jwt from 'jsonwebtoken';
const secret = 'my_app_secret';
const payload = {user_name:'Jack', id:3, email: '1234@gmail.com'};
const token = jwt.sign(payload, secret, { expiresIn: '1h' });

上面代码中通过jwt.sign来生成一个token,

参数意义:

  • payload:载体,一般把用户信息作为载体来生成token
  • secret:秘钥,可以是字符串也可以是文件
  • expiresIn:过期时间 1h表示一小时

在登录中返回token

import * as crypto from 'crypto';
import * as jwt from 'jsonwebtoken';
async login(ctx){
 //从数据库中查找对应用户
 const user = await userRespository.findOne({
  where: {
   name: user.name
  }
 });
 //密码加密
 const psdMd5 = crypto
  .createHash('md5')
  .update(user.password)
  .digest('hex');
 //比较密码的md5值是否一致 若一致则生成token并返回给前端
 if (user.password === psdMd5) {
  //生成token
  token = jwt.sign(user, secret, { expiresIn: '1h' });
  //响应到前端
  ctx.body = {
   token
  }
 }
}

前端拦截器

前端通过登录拿到返回过来的token,可以将它存在localStorage里,然后再以后的请求中把token放在请求头的Authorization里带给服务端。

这里以axios请求为例,在发送请求时,通过请求拦截器把token塞到header里:

//请求拦截器
axios.interceptors.request.use(function(config) {
  //从localStorage里取出token
  const token = localStorage.getItem('tokenName');
  //把token塞入Authorization里
  config.headers.Authorization = `Bearer ${token}`;
  
  return config;
 },
 function(error) {
  // Do something with request error
  return Promise.reject(error);
 }
);

服务端处理前端发送过来的Token
前端发送请求携带token,后端需要判断以下几点:

token是否正确,不正确则返回错误
token是否过期,过期则刷新token 或返回401表示需要从新登录

关于上面两点,需要在后端写一个中间件来完成:

app.use((ctx, next) => {
 if (ctx.header && ctx.header.authorization) {
  const parts = ctx.header.authorization.split(' ');
  if (parts.length === 2) {
   //取出token
   const scheme = parts[0];
   const token = parts[1];
   if (/^Bearer$/i.test(scheme)) {
    try {
     //jwt.verify方法验证token是否有效
     jwt.verify(token, secret.sign, {
      complete: true
     });
    } catch (error) {
     //token过期 生成新的token
     const newToken = getToken(user);
     //将新token放入Authorization中返回给前端
     ctx.res.setHeader('Authorization', newToken);
    }
   }
  }
 }
 return next().catch(err => {
  if (err.status === 401) {
   ctx.status = 401;
   ctx.body =
    'Protected resource, use Authorization header to get access\n';
  } else {
   throw err;
  }});
 });

上面中间件是需要验证token时都需要走这里,可以理解为拦截器,在这个拦截器中处理判断token是否正确及是否过期,并作出相应处理。

后端刷新token 前端需要更新token
后端更换新token后,前端也需要获取新token 这样请求才不会报错。

由于后端更新的token是在响应头里,所以前端需要在响应拦截器中获取新token。

依然以axios为例:

//响应拦截器
axios.interceptors.response.use(function(response) {
  //获取更新的token
  const { authorization } = response.headers;
  //如果token存在则存在localStorage
  authorization && localStorage.setItem('tokenName', authorization);
  return response;
 },
 function(error) {
  if (error.response) {
   const { status } = error.response;
   //如果401或405则到登录页
   if (status == 401 || status == 405) {
    history.push('/login');
   }
  }
  return Promise.reject(error);
 }
);

总结

以上所述是小编给大家介绍的koa+jwt实现token验证与刷新功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 参考教程
Dec 29 Javascript
javascript温习的一些笔记 基础常用知识小结
Jun 22 Javascript
js精度溢出解决方案
Dec 02 Javascript
javascript基于DOM实现权限选择实例分析
May 14 Javascript
js滚轮事件兼容性问题需要注意哪些
Nov 15 Javascript
vue.js+Element实现表格里的增删改查
Jan 18 Javascript
利用prop-types第三方库对组件的props中的变量进行类型检测
May 02 Javascript
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
Aug 30 Javascript
elementUI 设置input的只读或禁用的方法
Oct 30 Javascript
JS浅拷贝和深拷贝原理与实现方法分析
Feb 28 Javascript
原生js实现自定义消息提示框
Nov 19 Javascript
vue3使用vuedraggable实现拖拽功能
Apr 06 Vue.js
深入理解JavaScript 箭头函数
May 30 #Javascript
socket在egg中的使用实例代码详解
May 30 #Javascript
深入了解JavaScript 私有化
May 30 #Javascript
jQuery模拟html下拉多选框的原生实现方法示例
May 30 #jQuery
Vue CL3 配置路径别名详解
May 30 #Javascript
Vue CLI3中使用compass normalize的方法
May 30 #Javascript
通过实践编写优雅的JavaScript代码
May 30 #Javascript
You might like
在PHP中养成7个面向对象的好习惯
2010/07/17 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
Zend Framework开发入门经典教程
2016/03/23 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
基于JavaScript自定义构造函数的详解说明
2013/04/24 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
jquery实现类似淘宝星星评分功能实例
2014/09/12 Javascript
jQuery基础知识小结
2014/12/22 Javascript
浅谈javascript面向对象程序设计
2015/01/21 Javascript
javascript实现简单的二级联动
2015/03/19 Javascript
Javascript调用函数方法的几种方式介绍
2015/03/20 Javascript
js实现匹配时换色的输入提示特效代码
2015/08/17 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
Node.js模拟发起http请求从异步转同步的5种用法
2018/09/26 Javascript
[51:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第二局
2016/03/03 DOTA
wxpython 学习笔记 第一天
2009/03/16 Python
python中反射用法实例
2015/03/27 Python
浅析Python中的多进程与多线程的使用
2015/04/07 Python
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
2018/02/21 Python
python 环境搭建 及python-3.4.4的下载和安装过程
2019/07/20 Python
python根据文本生成词云图代码实例
2019/11/15 Python
python paramiko远程服务器终端操作过程解析
2019/12/14 Python
用python实现学生管理系统
2020/07/24 Python
什么是Python包的循环导入
2020/09/08 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
2021/03/04 Python
CSS3 实现的火焰动画
2020/12/07 HTML / CSS
墨西哥网上超市:Superama
2018/07/10 全球购物
财务分析个人的自荐书范文
2013/11/24 职场文书
自行车广告词大全
2014/03/21 职场文书
研究生导师推荐信
2014/09/06 职场文书
九九重阳节标语
2014/10/07 职场文书
工作检讨书范文
2015/01/23 职场文书
2015年信息化建设工作总结
2015/07/23 职场文书
检讨书怎么写?
2019/06/21 职场文书
MySQL数据库压缩版本安装与配置详细教程
2021/05/21 MySQL