基于JWT的Token身份验证
身份验证,是指通过一定的手段,完成对用户身份的确认。为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie、session和token。
1.Cookie
cookie是指浏览器里能够永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
在用户第一次登陆成功后,服务端就将用户的个人信息等写入cookie对象中,然后将此cookie对象发送给对应的客户端,客户端就存储下这个cookie。此后每次客户端向服务端发送请求时,就带上这个cookie对象,便于服务端进行用户认证和分辨,以决定是否提供服务。
由于cookie是存储在客户端的,服务端的仅仅存储一份信息,不会占据太多的磁盘空间,服务端的压力很小。
但是由于cookie对象中会存储大量的用户相关信息,而且每个请求都会携带该对象,因此存在传输效率的问题,同时一旦cookie被有心人截获,那么用户信息就被完全暴露,极易导致用户信息的泄露和伪装身份的恶意访问,给软件安全带来一定的隐患。
2.Session
session是对cookie的进一步优化。cookie会存储用户的大部分相关信息,从而导致效率低下和安全不能保障等问题,因此session的基本逻辑是将用户信息存储在服务器端,生成一个唯一字符串来对应每一个用户,然后仅将此唯一的字符串返回给客户端。
不用传输大量的用户相关数据,保证了传输效率和传输的安全性。一般情况,session存储于cookie中,利用cookie对象来传输session数据。
但是此种操作下,每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。同时如果服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
3.Token
Token的身份验证是无状态的,客户端登陆成功后,服务端会生成一个token并把它返还给客户端,服务端不再保存该Token。客户端每次发送请求时也会携带Token。由于这里的Token是服务端用自己的密钥签名的,当它接受到客户的Token时,只需要用自己的密钥去验证,就可以判断这个Token是不是自己签发的。
Token验证的具体流程如下:
- 客户端使用用户名和密码等向服务端请求登录
- 服务端通过验证,返回Token给客户端
- 客户端将Token写入本地缓存,并且后续请求均携带该Token
- 服务端接受到服务请求,验证Token,验证通过则提供服务,否则拒绝响应。

基于Token的身份验证方式,使我们不用将用户信息存在服务器或Session中,此种方式既解决了传输效率和安全问题,同时也解决了服务器内存压力过大的问题。同时由于Token无状态和不存储Session信息,一次,即使对于负载均衡问题,也能够将用户请求传递到任何一台服务器上,并进行解析和验证,而不需要担心请求必须发送到某一特定机器上的问题。
4.基于JWT的Token身份验证
经过以上的调研和分析,我们发现基于Token的身份验证相较于其他的身份验证方式有着更好的适用性和安全性。因此,我们最终选择Token进行身份验证。
实施Token的验证方法很多,其中比较常用的便是JWT验证。JWT全称JSON Web Token。JWT标准的Token包括header、payload、signature三部分,中间用点分开,并且使用Base64编码。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3VyaWQiOjQ0LCJpYXQiOjE7MTk5NjcyMDZ9.UPcMrinrYLr5ZtcWLDqeuxRlUpEQEwk-im8EGyjXTiJk_f0j1bIJWhe34akHfvo0fjbUDK4lo9ADXbUy3a2wmYL_A
第一部分header,放入token的类型(“JWT”)和算法名称(RS256等);第二部分payload,放入用户的不敏感信息(用户id等);第三部分signature,根据不公开的秘钥加上header中声明的算法,生成特定的签名。最终三部分组合起来即形成了token,发送给客户端。
Token认证部分,对Token使用不公开的秘钥和声明的算法进行解密分析,若成功解密即通过认证,若解密错误即认证失败。
5.以Node.js为例的JWT验证
此处以RS256加密算法为例进行举例分析。
首先生成秘钥文件,以便后续加密使用:
ssh-keygen -t rsa -b 2048 -f private.key
随后根据秘钥,创建对应的公钥:
openssl rsa -in private.key -pubout -outform PEM -out public.key
秘钥创建完成之后,即可进行Token的签发与认证。
JWT的签发
const jwt = require('jsonwebtoken')
const fs = require('fs')
const path = require('path')
async function generateToken(data) {
let creatTime = Math.floor(Date.now() / 1000);
const privateKey = await fs.readFileSync(path.join(__dirname, 'xxxx.key'));
let obj = {
data,
expire: creatTime + 60 * 30
}
const token = jwt.sign(obj, privateKey, {algorithm: 'RS256'});
return token;
}
以RS256算法和不公开的私钥,以及待存储数据和过期时间进行加密和签证,以生成最终可用的token返回给客户端。
JWT的验证
const jwt = require('jsonwebtoken')
const fs = require('fs')
const path = require('path')
async function verifyToken(token) {
const publicKey = fs.readFileSync(path.join(__dirname, 'xxx.key'));
let result;
try {
result = jwt.verify(token, publicKey)
let {exp = 0} = result, current = Math.floor(Date.now() / 1000);
if (current <= exp) {
res = result;
}
} catch (e) {
result = 'err';
}
return result;
}
对Token进行解密验证,并验证Token是否过期。
Token拦截器
app.use(function (req, res, next) {
if (req._parsedUrl.pathname != '/login') {
let tk = req.headers.authorization;
if (tk.substr(0, 5) == 'test-') {
tk = tk.substring(5);
}
token.verifyToken(tk).then( function (result) {
if (result == 'err') {
res.send({
"data": {},
"code": 0,
"msg": "Token is wrong!"
})
}
else {
next();
}
});
}
else {
next();
}
})
在所有请求到来时,首先进行Token认证,认证通过则提供服务,否则直接拒绝服务。
基于JWT的Token身份验证的更多相关文章
- ASP.NET Web API 2系列(四):基于JWT的token身份认证方案
1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...
- 基于JWT的token身份认证方案
一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...
- 基于JWT的token身份认证方案(转)
https://www.cnblogs.com/xiangkejin/archive/2018/05/08/9011119.html 一.使用JSON Web Token的好处? 1.性能问题. JW ...
- .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...
- ASP.NET WebApi 基于JWT实现Token签名认证
一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...
- ASP.NET Core WebApi基于JWT实现接口授权验证
一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...
- token 与 基于JWT的Token认证
支持跨域访问,无状态认证 token特点 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输 无状态(也称:服务端可扩展行): ...
- Nginx集群之基于Redis的WebApi身份验证
目录 1 大概思路... 1 2 Nginx集群之基于Redis的WebApi身份验证... 1 3 Redis数据库... 2 4 Visualbox ...
- 基于JWT的Token开发案例
代码地址如下:http://www.demodashi.com/demo/12531.html 0.准备工作 0-1运行环境 jdk1.8 maven 一个能支持以上两者的代码编辑器,作者使用的是ID ...
随机推荐
- Python - //和/的区别
/ 表示浮点数除法,返回浮点结果; // 表示整数除法,返回不大于结果的一个最大的整数 print("6 // 4 = " + str(6 // 4)) print("6 ...
- Pytest系列(12)- 测试结果生成HTML报告插件之pytest-html的详细使用
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 环境前提 Python3.6+ 安 ...
- Abp Vnext3 vue-admin-template(二用户退出)
先修改用户退出,中午有点困先改简单的 退出代码在src\layout\components\Navbar.vue代码如下,讲流程这里不需要修改 methods: { toggleSideBar() { ...
- (4)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Cloud开发环境的准备和Lombok安装步骤
开发环境的准备主要涉及三个方面:JDK.Maven.Spring Tools 4 for Eclipse. 1.JDK JDK 的版本用 1.8 即可,环境变量大家自行去配置.配置好环境变量,在命 ...
- ThinkCMF5.1主要特性
更改框架协议为MIT,让你更自由地飞 基于ThinkPHP 5.1重构,但核心代码兼容5.0版本,保证老用户最小升级成本 增加对swoole支持,同时支持swoole协程和全同步模式(请单独安装扩展) ...
- PHP中的MySQLi扩展学习(二)mysqli类的一些少见的属性方法
虽说是少见的一些属性方法,但是可能还是有不少同学在日常的开发中使用过,这里只是学习了可能相对来说我们用得比较少的一些 mysqli 的属性或方法.就当是扩展一下自己的知识体系. 切换用户 首先就是切换 ...
- xadmin使用富文本
环境:pycharm django1.11.20 python2.7 后台xadmin(根据网络各种资料实现) 本教程接上篇如何安装 xadmin,如何不清楚,请看上一篇(django安装xadmin ...
- P5305-[GXOI/GZOI2019]旧词【树链剖分,线段树】
正题 题目链接:https://www.luogu.com.cn/problem/P5305 题目大意 给一棵有根树和\(k\),\(Q\)次询问给出\(x,y\)求 \[\sum_{i=1}^{x} ...
- Python3入门系列之-----内置的文件操作模块OS
前言 在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告(从而发送测试报告邮件),经常要对大量文件和大量路径进行操作,这个时候就需要用到os模块. 使用前 ...
- bootstrap inputfile 使用-上传,回显
近期用bootstrap 做前端的上传,功能涉及到上传时就是召网上的教程随便弄一搜一大把,但是做到修改页面时候不知道页面该如何回显,折腾了一阵子才完成遂记录下来希望能给看到的小伙伴有点启发吧. 首先是 ...