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获取用户信息,看是否有用户信息及用户信息是否正确 服务鉴权 微服务中,一般有多个服务,服务与服务之间相互调用时,有的服务接口比较敏感,比如资金服务,不允 ...
随机推荐
- Delphi在系统菜单中添加菜单项
unit dy219; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- SimpleMembership,成员资格提供程序、 通用的提供者和新的 ASP.NET 4.5 Web 窗体和 ASP.NET MVC 4 模板
ASP.NET MVC 4 互联网模板中添加一些新的. 非常有用的功能,构建 SimpleMembership.这些更改将添加一些很有特色,像很多更简单. 可扩展会员 API 和 OAuth 的支持. ...
- QT多个UI文件加入一个项目
这样可在多个UI界面上进行分部开发.避免都在一个UI下太凌乱…… 在网上找了一些资料,很少有介绍这方面的,以及类似这样项目的源码. 看 一些基本控件的使用时,想到了一种方法:使用gridLayout控 ...
- .net core 2.0 dbfirst 报 dotnet ef 未找到与命令“dotnet-ef”匹配的可执行文件的解决办法
问题描述: 最近研究了一段时间.netcore dbfirst,新建类库用来生成实体模型,执行命令总是提示 未找到与命令“dotnet-ef”匹配的可执行文件,根据网上的解决办法引用 Microsof ...
- Spring Boot的学习之路(03):基础环境搭建,做好学习前的准备工作
1. 前言 <论语·魏灵公>:"工欲善其事,必先利其器.居是邦也,事其大夫之贤者,友其士之仁者." 工欲善其事必先利其器.我们在熟悉一个陌生项目的时候,首先会大概去看一 ...
- vue数据加载等待组件
关于loading组件的. loading.vue <template> <div class="loading"> <div class=" ...
- Kafka 学习之路(一)—— Kafka简介
一.简介 Apache Kafka是一个分布式的流处理平台.它具有以下特点: 支持消息的发布和订阅,类似于RabbtMQ.ActiveMQ等消息队列: 支持数据实时处理: 能保证消息的可靠性投递: 支 ...
- composer-laravel-China源和官方源
composer config -g repo.packagist composer https://repo.packagist.org composer config -g repo.packag ...
- 编译gd库出错
不知道大家有没有遇到在 X64 RedHat5 或者 RedHat4 下.编译安装PHP环境的时候. 安装了libxml,zlib,jpeg,libpng,freetype,libart_lgpl, ...
- Java8新特性——lambda表达式.(案例:完全数分类)
需求:输入一个数,判断其类型(完全数,过剩数,不足数) 完全数:自身之外所有因数和==自身 过剩数:自身之外所有因数和>自身 不足数:自身之外所有因数和<自身 package cn._3. ...