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 篱式条件判断
Aug 22 Javascript
js window.event对象详尽解析
Feb 17 Javascript
jquery检测input checked 控件是否被选中的方法
Mar 26 Javascript
JavaScript中的setMilliseconds()方法使用详解
Jun 11 Javascript
JavaScript修改作用域外变量的方法
Mar 25 Javascript
jQuery子元素过滤选择器用法示例
Sep 09 Javascript
svg动画之动态描边效果
Feb 22 Javascript
原生js中ajax访问的实例详解
Sep 19 Javascript
Three.js实现绘制字体模型示例代码
Sep 26 Javascript
微信小程序实现图片压缩功能
Jan 26 Javascript
react build 后打包发布总结
Aug 24 Javascript
JavaScript代码简化技巧实例解析
Sep 09 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安全防范技巧分享
2011/11/03 PHP
PHP+Ajax实现验证码的实时验证
2016/07/20 PHP
ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解
2019/04/02 PHP
PHP7新功能总结
2019/04/14 PHP
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
javascript判断移动端访问设备并解析对应CSS的方法
2015/02/05 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
canvas红包照片实例分享
2017/02/28 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
jQuery Masonry瀑布流布局神器使用详解
2017/05/25 jQuery
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
基于jQuery.i18n实现web前端的国际化
2018/05/04 jQuery
详解vue的diff算法原理
2018/05/20 Javascript
jQuery实现table表格信息的展开和缩小功能示例
2018/07/21 jQuery
浅谈Vue 性能优化之深挖数组
2018/12/11 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
2018/12/13 Javascript
js实现图片放大并跟随鼠标移动特效
2019/01/18 Javascript
在vue项目中引入vue-beauty操作方法
2019/02/11 Javascript
layui实现下拉复选功能的例子(包括数据的回显与上传)
2019/09/24 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
php使用递归与迭代实现快速排序示例
2014/01/23 Python
Python正则获取、过滤或者替换HTML标签的方法
2016/01/28 Python
用python与文件进行交互的方法
2018/03/01 Python
python监控nginx端口和进程状态
2019/09/06 Python
基于python实现上传文件到OSS代码实例
2020/05/09 Python
超酷炫 CSS3垂直手风琴菜单
2016/06/28 HTML / CSS
详解HTML5 Canvas绘制不规则图形时的非零环绕原则
2016/03/21 HTML / CSS
世界知名接发和假发品牌:Poze Hair
2017/03/08 全球购物
Tessabit美国:集世界奢侈品和设计师品牌的意大利精品买手店
2020/06/29 全球购物
什么是典型的软件三层结构?软件设计为什么要分层?软件分层有什么好处?
2012/03/14 面试题
个人贷款担保书
2014/04/01 职场文书
农民工工资承诺书大全
2015/05/04 职场文书
python小程序之飘落的银杏
2021/04/17 Python
APP界面设计技巧和注意事项
2022/04/29 杂记