koa2服务端使用jwt进行鉴权及路由权限分发
大体思路
后端书写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: ,
token: token,
msg: '登录成功'
}
}else{
return ctx.body = {
code: ,
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 === ){
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进行鉴权及路由权限分发的更多相关文章
- 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...
- 认证鉴权与API权限控制在微服务架构中的设计与实现(四)
引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...
- 无线端安全登录与鉴权一之Kerberos
无线端登录与鉴权是安全登录以及保证用户数据安全的第一步,也是最重要的一步.之前做过一个安全登录与鉴权的方案,借这个机会,系统的思考一下,与大家交流交流 先介绍一下TX系统使用的Kerberos方案,参 ...
- SpringCloud 2020.0.4 系列之 JWT用户鉴权
1. 概述 老话说的好:善待他人就是善待自己,虽然可能有所付出,但也能得到应有的收获. 言归正传,之前我们聊了 Gateway 组件,今天来聊一下如何使用 JWT 技术给用户授权,以及如果在 Gate ...
- vue.js+koa2项目实战(四)搭建koa2服务端
搭建koa2服务端 安装两个版本的koa 一.版本安装 1.安装 koa1 npm install koa -g 注:必须安装到全局 2.安装 koa2 npm install koa@2 -g 二. ...
- 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用
Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...
- [转]Node.js 应用:Koa2 使用 JWT 进行鉴权
本文转自:https://www.cnblogs.com/linxin/p/9491342.html 前言 在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行 ...
- Node.js 应用:Koa2 使用 JWT 进行鉴权
前言 在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行保护,那么别人就可以很容易地获取并调用这些 API 进行操作.那么服务器端要如何进行鉴权呢? Json ...
- spring cloud jwt用户鉴权及服务鉴权
用户鉴权 客户端请求服务时,根据提交的token获取用户信息,看是否有用户信息及用户信息是否正确 服务鉴权 微服务中,一般有多个服务,服务与服务之间相互调用时,有的服务接口比较敏感,比如资金服务,不允 ...
随机推荐
- 使用scratchbox2建立交叉编译环境
使用scratchbox2建立交叉编译环境,使交叉编译不再烦人..... os:ubuntu 12.04.4 x64 1. 安装相关工具sudo apt-get install debootstrap ...
- Delphi线程类 DIY(把类指针作为参数传进去,就可以执行类里面的方法啦)
Delphi 封装了一个很强大的线程类 TThread, 我们也自己动手制作一个简单的线程类 首先Type一个类 type TwwThread = class constructor Create; ...
- Z Order of Controls in Delphi FireMonkey(Tom Yu的博客)
Get and set the Z Order of controls at runtime in Delphi FireMonkey. This is a follow on to my earli ...
- delphi7 xml通用解析转换为stringgrid
对于有n多记录的xml,可以填充到stringgrid中 其中 vkeynode 为 xml中 重复节点 function CommonAnalyzeXml(vxml,vkeynode: string ...
- Django预备知识
http协议 url: 协议://域名(IP)+端口(80)/路径?参数(a=1&b=2) 示例:https://www.baidu.com/s/?wd=aaa MVC M:mdoel 与数据 ...
- 使用熔断器仪表盘监控(hystrix)
概述 在 Ribbon 和 Feign 项目增加 Hystrix 仪表盘功能,两个项目的改造方式相同. 在 pom.xml 中增加依赖 <dependency> <groupId&g ...
- 分享Sql Server 2008 r2 数据备份,同步服务器数据(二.本地发布,订阅)
上一篇文章中写到了数据库的本地备份,这一篇主要分享一下关于不同服务器的数据备份,主要是使用sql server中的本地发布,本地订阅功能,在数据库的读写分离中,也会经常性的用到这个功能. 复制-> ...
- PWN菜鸡入门之栈溢出(1)
栈溢出 一.基本概念: 函数调用栈情况见链接 基本准备: bss段可执行检测: gef➤ b main Breakpoint at . gef➤ r Starting program: /mnt/ ...
- 【java爬虫】网络爬虫思路
主要是针对某个单独的网站进行页面的爬取,方式有好多种,记录一下大体的思路. 方法1: a.通过http请求获取返回的静态页面. b.将返回的字符串页面进行split,切割成字符串数组. c.遍历字符串 ...
- Linux下多网卡绑定bond及模式介绍
[介绍] 网卡bond一般主要用于网络吞吐量很大,以及对于网络稳定性要求较高的场景. 主要是通过将多个物理网卡绑定到一个逻辑网卡上,实现了本地网卡的冗余,带宽扩容以及负载均衡. Linux下一共有七种 ...