​ 身份验证,是指通过一定的手段,完成对用户身份的确认。为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,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身份验证的更多相关文章

  1. ASP.NET Web API 2系列(四):基于JWT的token身份认证方案

    1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...

  2. 基于JWT的token身份认证方案

    一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...

  3. 基于JWT的token身份认证方案(转)

    https://www.cnblogs.com/xiangkejin/archive/2018/05/08/9011119.html 一.使用JSON Web Token的好处? 1.性能问题. JW ...

  4. .NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)

    上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...

  5. ASP.NET WebApi 基于JWT实现Token签名认证

    一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...

  6. ASP.NET Core WebApi基于JWT实现接口授权验证

    一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...

  7. token 与 基于JWT的Token认证

    支持跨域访问,无状态认证 token特点 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输 无状态(也称:服务端可扩展行): ...

  8. Nginx集群之基于Redis的WebApi身份验证

    目录 1       大概思路... 1 2       Nginx集群之基于Redis的WebApi身份验证... 1 3       Redis数据库... 2 4       Visualbox ...

  9. 基于JWT的Token开发案例

    代码地址如下:http://www.demodashi.com/demo/12531.html 0.准备工作 0-1运行环境 jdk1.8 maven 一个能支持以上两者的代码编辑器,作者使用的是ID ...

随机推荐

  1. IS(上升子序列)

    前言:   这是一篇杂题选讲+作者口胡的博客,不喜勿喷. 正文:   提示:在阅读时请留意加粗的字体是"极长"还是"最长".   今天改题时碰到了一道关于线段树 ...

  2. Python - 导入的位置

    导入的是什么 导入是将 Python 的一些功能函数放到当前的脚本中使用 不导入的功能无法直接在当前脚本使用(除了 python 自带的内置函数) Python 有很多第三方功能,假设想要使用,都必须 ...

  3. Typora画各类流程图、甘特图、饼图等详细文档

    Draw Diagrams With Markdown August 15, 2016 by typora.io Typora supports some Markdown extensions fo ...

  4. Python中正则表达式简介

    目录 一.什么是正则表达式 二.正则表达式的基础知识 1. 原子 1)普通字符作为原子 2)非打印字符作为原子 3) 通用字符作为原子 4) 原子表 2. 元字符 1)任意匹配元字符 2)边界限制元字 ...

  5. 数据导出生成Excel附件使用POI的HSSFWorkbook对象

    比较常用的实现Java导入.导出Excel的技术有两种Jakarta POI和Java Excel.Jakarta POI 是一套用于访问微软格式文档的Java API.Jakarta POI有很多组 ...

  6. go命令帮助

    Go is a tool for managing Go source code. go-->管理go源码的工具-->管理工具,包含很多功能命令 Usage: go <command ...

  7. prometheus从零开始

    本次的想法是做服务监控 并告警  主要线路如下图所示 1.运行prometheus  docker方式 docker run -itd \ -p 9090:9090 \ -v /opt/prometh ...

  8. Java比较两个浮点数

    浮点数的基本数据类型不能用==比较,包装数据类型不能用 equals 比较 浮点数的表示 在计算机系统中,浮点数采用 符号+阶码+尾数 进行表示.在Java中,单精度浮点数float类型占32位,它的 ...

  9. RMQ区间最值查询

    RMQ区间最值查询 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A, 回答若干询问RMQ(A,i,j)(i,j<= ...

  10. phpmyadmin 设置密码

    例如 xampp 安装路径为 /opt/lampp/, copy 一份默认的配置 cp /opt/lampp/phpmyadmin/libraries/config.default.php /opt/ ...