​ 身份验证,是指通过一定的手段,完成对用户身份的确认。为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,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. IPsec NAT-T说明和环境搭建

    1. IPsec与NAT的关系 NAT作为一个IPV4的地址转换协议,它最初的目的是用来最解决IPv4地址不足的问题.通过NAT协议,局域网内的多个主机可以共同使用一个公网地址,这在很大程度上减轻了I ...

  2. 两种方式配置vue全局方法

    目录 1,前言 2,第一种方式 3,第二种方式 1,前言 在Vue项目开发中,肯定会有这样一个场景:在不同的组件页面用到同样的方法,比如格式化时间,文件下载,对象深拷贝,返回数据类型,复制文本等等.这 ...

  3. uniapp 获取用户手机号

    参考资料: 微信小程序官方文档 uniapp开发微信小程序获取用户手机号 页面增加一个按钮 <button open-type="getPhoneNumber" @getph ...

  4. 地址栏url中去掉所有参数

    1.地址栏url中去掉所有参数,这个是纯前端解决,很多时候页面跳转时候会选择在url后面带参数过去,(使用?&),方便传也方便取,但是我们要做的是不要让页面的一些请求参数暴露在外面 正常项目工 ...

  5. dotnet 读 WPF 源代码笔记 渲染收集是如何触发

    在 WPF 里面,渲染可以从架构上划分为两层.上层是 WPF 框架的 OnRender 之类的函数,作用是收集应用程序渲染的命令.上层将收集到的应用程序绘制渲染的命令传给下层,下层是 WPF 的 GF ...

  6. [第十四篇]——Docker Machine之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker Machine 简介 Docker Machine 是一种可以让您在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机. Docker Mac ...

  7. oracle table()函数

    PL/SQL表---table()函数用法/* PL/SQL表---table()函数用法:利用table()函数,我们可以将PL/SQL返回的结果集代替table. oracle内存表在查询和报表的 ...

  8. 加入Erlang社区-指引

    国内暂且没有发现较活跃.人气较高的论坛或者社区,偶然发现Erlang官网的Community页面描述了一个Slack交流平台,里面有众多异国他乡的大佬,感兴趣的.有技术疑问的都可以加入看看. 加入教程 ...

  9. Thinkphp5 主动式 计划任务 支持windows和linux

    百度搜索过相关的php计划任务的资料,特别是搜索thinkphp的计划任务,目前能明确实现的都是被动式的,就是通过tp3.2自带的计划任务类实现,通过挂钩子的形式,用户访问网站的时候就执行计划任务,这 ...

  10. springboot 配置 application.properties相关

    springboot 有读取外部配置文件的方法,如下优先级: 第一种是在jar包的同一目录下建一个config文件夹,然后把配置文件放到这个文件夹下.第二种是直接把配置文件放到jar包的同级目录.第三 ...