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+CSS实现仿Mootools竖排弹性动画菜单效果
Oct 14 Javascript
jQuery simplePage+AJAX plus分页插件用法实例
Feb 17 Javascript
批量下载对路网图片并生成html的实现方法
Jun 07 Javascript
Javascript 动态改变imput type属性
Nov 01 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
Jan 12 Javascript
详解支持Angular 2的表格控件
Jan 19 Javascript
Js实现中国公民身份证号码有效性验证实例代码
May 03 Javascript
Vue 中对图片地址进行拼接的方法
Sep 03 Javascript
Vue 中的受控与非受控组件的实现
Dec 17 Javascript
利用es6 new.target来对模拟抽象类的方法
May 10 Javascript
利用JavaScript将Excel转换为JSON示例代码
Jun 14 Javascript
javascript实现计算器功能
Mar 30 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
ThinkPHP 防止表单重复提交的方法
2011/08/08 PHP
php FLEA中二叉树数组的遍历输出
2012/09/26 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
php 判断服务器操作系统的类型
2014/02/17 PHP
php中stream(流)的用法
2014/03/25 PHP
PHP中使用CURL模拟登录并获取数据实例
2014/07/01 PHP
thinkphp模板用法和内容输出实例
2014/11/28 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
jquery获取radio值实例
2014/10/16 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
2015/12/02 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
AngularJS 让人爱不释手的八种功能
2016/03/23 Javascript
angular2倒计时组件使用详解
2017/01/12 Javascript
zTree实现节点修改的实时刷新功能
2017/03/20 Javascript
详解Vue用自定义指令完成一个下拉菜单(select组件)
2017/10/31 Javascript
微信小程序云开发使用方法新手初体验
2019/05/16 Javascript
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
2020/08/03 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
如何在JavaScript中等分数组的实现
2020/12/13 Javascript
PyQt5固定窗口大小的方法
2019/06/18 Python
Python批量修改图片分辨率的实例代码
2019/07/04 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
python爬虫实现爬取同一个网站的多页数据的实例讲解
2021/01/18 Python
解锁canvas导出图片跨域的N种姿势小结
2019/01/24 HTML / CSS
HTML5触摸事件(touchstart、touchmove和touchend)的实现
2020/05/08 HTML / CSS
自动化工程专业个人应聘自荐信
2013/09/26 职场文书
《春晓》教学反思
2014/04/20 职场文书
咖啡店创业计划书
2014/08/15 职场文书
家庭贫困证明
2014/09/23 职场文书
工作失职检讨书
2015/01/26 职场文书
小学教师暑期培训心得体会
2016/01/09 职场文书
2019个人工作计划书的格式及范文!
2019/07/04 职场文书
Go语言 详解net的tcp服务
2022/04/14 Golang