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 相关文章推荐
用prototype实现的简单小巧的多级联动菜单
Mar 24 Javascript
JavaScript 数组循环引起的思考
Jan 01 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
Apr 16 Javascript
js实现DOM走马灯特效的方法
Jan 21 Javascript
JS往数组中添加项性能分析
Feb 25 Javascript
jquery实现select下拉框美化特效代码分享
Aug 18 Javascript
jquery实现九宫格大转盘抽奖
Nov 13 Javascript
js 获取元素所有兄弟节点的实现方法
Sep 06 Javascript
AngularJS模板加载用法详解
Nov 04 Javascript
Vue表单控件绑定图文详解
Feb 11 Javascript
vue实现编辑器键盘抬起时内容跟随光标距顶位置向上滚动效果
May 28 Javascript
深入理解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+redis实现商城秒杀功能
2020/11/19 PHP
php的单例模式及应用场景详解
2021/02/27 PHP
基于jquery实现的可以编辑选择的下拉框的代码
2010/11/19 Javascript
jquery ui对话框实例代码
2013/05/10 Javascript
如何防止回车(enter)键提交表单
2014/05/11 Javascript
JS实现让访问者自助选择网页文字颜色的方法
2015/02/24 Javascript
JavaScript中的getMilliseconds()方法使用详解
2015/06/10 Javascript
AngularJS学习笔记之ng-options指令
2015/06/16 Javascript
js+css实现回到顶部按钮(back to top)
2016/03/02 Javascript
jquery对象访问是什么及使用方法介绍
2016/05/03 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
使用ECharts实现状态区间图
2018/10/25 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
2019/10/14 Javascript
vue中实现高德定位功能
2019/12/03 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
Eclipse + Python 的安装与配置流程
2013/03/05 Python
python中将字典转换成其json字符串
2014/07/16 Python
Python读取环境变量的方法和自定义类分享
2014/11/22 Python
用Python展示动态规则法用以解决重叠子问题的示例
2015/04/02 Python
C#返回当前系统所有可用驱动器符号的方法
2015/04/18 Python
简单学习Python time模块
2016/04/29 Python
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
python实现单链表中删除倒数第K个节点的方法
2018/09/28 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
CSS3网格的三个新特性详解
2014/04/04 HTML / CSS
使用css实现android系统的loading加载动画
2019/07/25 HTML / CSS
护士自我鉴定范文
2013/10/06 职场文书
公司总经理岗位职责范本
2014/08/15 职场文书
反腐倡廉警示教育活动心得体会
2014/09/04 职场文书
2014年村委会工作总结
2014/11/24 职场文书
护理专业自我评价
2015/03/11 职场文书
开会通知短信大全
2015/04/20 职场文书
学会感恩主题班会
2015/08/12 职场文书
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python