koa2服务端使用jwt进行鉴权及路由权限分发的流程分析


Posted in Javascript onJuly 22, 2019

大体思路

后端书写REST api时,有一些api是非常敏感的,比如获取用户个人信息,查看所有用户列表,修改密码等。如果不对这些api进行保护,那么别人就可以很容易地获取并调用这些 api 进行操作。

所以对于一些api,在调用之前,我们在服务端必须先对操作者进行“身份认证”,这就是所谓的鉴权。

Json Web Token 简称为 JWT,它定义了一种通信双方之间以 JSON 对象的形式安全传递信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名,复杂度较高,换来的是更可靠的安全系数。

整个认证的流程大体如下:

首先用户登录的接口是不用token认证的,因为这个接口本身就是token的产生来源。前端输入用户名和密码后请求服务器登录接口,服务器验证用户名密码正确后,生成token并返回给前端,前端存储token,并在后面的请求中把token带在请求头中传给服务器,服务器验证token有效,才可以进行下一步操作。

服务器生成token

由于我们的服务端使用 Koa2 框架进行开发,除了要使用到 jsonwebtoken 库之外,还要使用一个 koa-jwt 中间件,该中间件针对 Koa 对 jsonwebtoken 进行了封装,使用起来更加方便。

 const router = require('koa-router')();
const jwt = require('jsonwebtoken');
const userModel = require('../models/userModel.js');
router.post('/login', async (ctx) => {
 const data = ctx.request.body;const result = await userModel.findOne({
  name: data.name,
  password: data.password
 })
 if(result !== null){
  const token = jwt.sign({
   name: result.name,
   _id: result._id
  }, 'zhangnan', { expiresIn: '2h' });
  return ctx.body = {
   code: 200,
   token: token,
   msg: '登录成功'
  }
 }else{
  return ctx.body = {
   code: 400,
   token: null,
   msg: '用户名或密码错误'
  }
 }
});
module.exports = router;

(注意:这里暂时不讨论加盐加密校验,实际项目中密码不可能这样明文验证,这里只是为了着重讨论token鉴权。在验证了用户名密码正确之后,就可以调用 jsonwebtoken 的 sign() 方法来生成token,接收三个参数,第一个是载荷,用于编码后存储在 token 中的数据,也是验证 token 后可以拿到的数据;第二个是密钥,自己定义的,随便写个什么单词都可以,但是验证的时候一定要相同的密钥才能解码;第三个是options,可以设置 token 的过期时间。)

前端获取token

接下来就是前端获取 token,这里是在 vue.js 中使用 axios 进行请求,请求成功之后拿到 token 保存到 localStorage 中。

submit(){
 axios.post('/login', {
  name: this.username,
  password: this.password
 }).then(res => {
  if(res.code === 200){
   localStorage.setItem('token', res.data.token);
  }else{
   this.$message('登录失败')
  }
 })
}

然后前端在请求后端api时,就把 token 带在请求头中传给服务器进行验证。每次请求都要获取 localStorage 中的 token,这样很麻烦,这里使用了 axios 的请求拦截器,进行全局设置,对每次请求都进行了取 token 放到 headers 中的操作。

axios.interceptors.request.use(config => {
 const token = localStorage.getItem('token');
 config.headers.common['Authorization'] = 'Bearer ' + token;
 return config;
})

(这段代码,如果是vue项目,可以直接放在main.js中设置,表示每次请求前都会往请求头的authorization里塞一个token,至于那个Bearer 是koa-jwt的一个标识单词,方便解析)

服务器验证token

接下来服务器收到前端发过来的token后,就可以进行验证。

const koa = require('koa');
const koajwt = require('koa-jwt');
const app = new koa();

app.use(koajwt({
 secret: 'zhangnan'
}).unless({
  path: [/\/register/, /\/login/]
}));

(在这里没有定义错误处理函数,由于出现错误后会返回401,所以我直接就让前端来处理这种异常情况,给出一个错误的交互提示即可)

分析koa-jwt源码

我们在node_mudules里面找到koa-jwt/lib/resolvers文件夹下的auth-header.js文件,看下koa-jwt做了些什么

(可以看到它是先判断请求头中是否带了 authorization,如果有,则通过正则将 token 从 authorization 中分离出来,这里我们也看到了Bearer这个单词。如果没有 authorization,则代表了客户端没有传 token 到服务器,这时候就抛出 401 错误状态。)

再看看上一级的vertify.js。

(可以看到在 verify.js 中,它就是调用 jsonwebtoken 原生提供的 verify() 方法进行验证返回结果。jsonwebtoken 的 sign() 方法用于生成 token ,而 verify() 方法当然则是用来解析 token。属于jwt配对生产的两个方法,所以koa-jwt这个中间件也没做什么事,无非就是用正则解析请求头,调用jwt的vertify方法验证token,在koa-jwt文件夹的index.js中,koa-jwt还调用koa-unless进行路由权限分发)

以上就是json web token的大体流程。

总结

以上所述是小编给大家介绍的koa2服务端使用jwt进行鉴权及路由权限分发的流程分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JavaScript While 循环基础教程
Apr 05 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
Feb 17 Javascript
jqGrid增加时--判断开始日期与结束日期(实例解析)
Nov 08 Javascript
Jquery注册事件实现方法
May 18 Javascript
使用Browserify配合jQuery进行编程的超级指南
Jul 28 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖动基本操作
Nov 30 Javascript
JavaScript中push(),join() 函数 实例详解
Sep 06 Javascript
SeaJS中use函数用法实例分析
Oct 10 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
Jun 27 Javascript
JavaScript惰性求值的一种实现方法示例
Jan 11 Javascript
jquery实现Ajax请求的几种常见方式总结
May 28 jQuery
微信小程序登录对接Django后端实现JWT方式验证登录详解
Jul 29 Javascript
在小程序中推送模板消息的实现方法
Jul 22 #Javascript
javascript自定义日期比较函数用法示例
Jul 22 #Javascript
详解微信小程序自定义组件的实现及数据交互
Jul 22 #Javascript
教你30秒发布一个TypeScript包到NPM的方法步骤
Jul 22 #Javascript
详解vue为什么要求组件模板只能有一个根元素
Jul 22 #Javascript
微信小程序获取用户绑定手机号方法示例
Jul 21 #Javascript
Vue商品控件与购物车联动效果的实例代码
Jul 21 #Javascript
You might like
php实现查询百度google收录情况(示例代码)
2013/08/02 PHP
PHP文件读写操作相关函数总结
2014/11/18 PHP
JavaScript 直接操作本地文件的实现代码
2009/12/01 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
2015/10/28 Javascript
浅谈Cookie的生命周期问题
2016/08/02 Javascript
谈谈PHP中相对路径的问题与绝对路径的使用
2016/08/16 Javascript
微信小程序侧边栏滑动特效(左右滑动)
2017/01/23 Javascript
Jquery鼠标放上去显示全名的实现方法
2017/02/06 Javascript
jQuery实现手势解锁密码特效
2017/08/14 jQuery
初识 Vue.js 中的 *.Vue文件
2017/11/22 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
解决VUE框架 导致绑定事件的阻止冒泡失效问题
2018/02/24 Javascript
React props和state属性的具体使用方法
2018/04/12 Javascript
element-ui upload组件多文件上传的示例代码
2018/10/17 Javascript
vue-cli中vue本地实现跨域调试接口
2019/01/16 Javascript
LayUi数据表格自定义赋值方式
2019/10/26 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
Python 的 with 语句详解
2014/06/13 Python
python生成随机mac地址的方法
2015/03/16 Python
Django发送html邮件的方法
2015/05/26 Python
Python中list查询及所需时间计算操作示例
2018/06/21 Python
python中web框架的自定义创建
2019/09/08 Python
10行Python代码计算汽车数量的实现方法
2019/10/23 Python
Python selenium 自动化脚本打包成一个exe文件(推荐)
2020/01/14 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
详解Python IO编程
2020/07/24 Python
意大利在线眼镜精品店:Ottica Lipari
2019/11/11 全球购物
事业单位接收函
2014/01/10 职场文书
运动会演讲稿
2014/05/07 职场文书
领导班子奢靡之风查摆问题及整改措施
2014/09/27 职场文书
创业计划书之韩国烧烤店
2019/09/19 职场文书
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js
MongoDB误操作后使用oplog恢复数据
2022/04/11 MongoDB
Apache SeaTunnel实现 非CDC数据抽取
2022/05/20 Servers