身份验证

传统身份验证的方法

HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。

 

解决的方法就是,当用户请求登录的时候,如果没有问题,我们在服务端生成一条记录,这个记录里可以说明一下登录的用户是谁,然后把这条记录的 ID 号发送给客户端,客户端收到以后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,可以带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,如果可以,说明用户已经通过了身份验证,就把用户请求的数据返回给客户端。

 

上面说的就是 Session,我们需要在服务端存储为登录的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。我们可能需要在服务端定期的去清理过期的 Session 。

前端退出的话就清cookie。后端强制前端重新认证的话就清或者修改session。

 

如果是分布式部署,需要做多机共享session机制,实现方法可将session存储到数据库中或者redis中

基于 cookie 的机制很容易被 CSRF

存储

session、cookie、sessionStorage、localstorage的区别

session: 主要存放在服务器端,相对安全

cookie: 可设置有效时间,默认是关闭浏览器后失效,主要存放在客户端,并且不是很安全,可存储大小约为4kb

sessionStorage: 仅在当前会话下有效,关闭页面或浏览器后被清除

localstorage: 除非被清除,否则永久保存

基于 Token 的身份验证方法

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

 

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token,放入HTTP Header中的Authorization位
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

JWT,读作:jot ,表示:JSON Web Tokens 。JWT 标准的 Token 有三个部分:

header

payload

signature

 

中间用点分隔开,并且都会使用 Base64 编码,所以真正的 Token 看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
 

标准

Header

header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 HS256。

{

  "typ": "JWT",

  "alg": "HS256"

}

Payload(有效载荷)

Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:

iss:Issuer,发行者

sub:Subject,主题

aud:Audience,观众

exp:Expiration time,过期时间

nbf:Not before

iat:Issued at,发行时间

jti:JWT ID

Signature

Signature 部分其实就是对我们前面的 Header 和 Payload 部分进行签名,保证 Token 在传输的过程中没有被篡改或者损坏,签名的算法也很简单,但是,为了加密,所以除了 Header 和 Payload 之外,还多了一个密钥字段,完整算法为:

    Signature = HMACSHA256(

        base64UrlEncode(header) + "." +

        base64UrlEncode(payload),

        secret)

这部分内容有三个部分,先是用 Base64 编码的 header.payload ,再用加密算法加密一下,加密的时候要放进去一个 Secret密钥,这个密钥被存储在服务端。

 

使用注意

  1. payload 中不要存放敏感信息,因为可以被很容易地获取到;
  2. Token 在服务器没有存储,只能通过设置过期时间来让 Token 失效,也就是没有办法让 Token 主动失效,就没有办法做单点登录(可以考虑服务器进行存储)
  3. 保护好secret私钥,该私钥非常重要。
  4. 如果可以,请使用HTTPS协议,不!是务必使用HTTPS!

比较

可扩展性

随着应用程序的扩大和用户数量的增加,你必将开始水平或垂直扩展。session数据通过文件或数据库存储在服务器的内存中。在水平扩展方案中,你必须开始复制服务器数据,你必须创建一个独立的中央session存储系统,以便所有应用程序服务器都可以访问。否则,由于session存储的缺陷,你将无法扩展应用程序。解决这个挑战的另一种方法是使用 sticky session。你还可以将session存储在磁盘上,使你的应用程序在云环境中轻松扩展。这类解决方法在现代大型应用中并没有真正发挥作用。建立和维护这种分布式系统涉及到深层次的技术知识,并随之产生更高的财务成本。在这种情况下,使用JWT是无缝的;由于基于token的身份验证是无状态的,所以不需要在session中存储用户信息。我们的应用程序可以轻松扩展,因为我们可以使用token从不同的服务器访问资源,而不用担心用户是否真的登录到某台服务器上。你也可以节省成本,因为你不需要专门的服务器来存储session。为什么?因为没有session!

注意:如果你正在构建一个小型应用程序,这个程序完全不需要在多台服务器上扩展,并且不需要RESTful API的,那么session机制是很棒的。 如果你使用专用服务器运行像Redis那样的工具来存储session,那么session也可能会为你完美地运作!

安全性

JWT签名旨在防止在客户端被篡改,但也可以对其进行加密,以确保token携带的claim 非常安全。JWT主要是直接存储在web存储(本地/session存储)或cookies中。 JavaScript可以访问同一个域上的Web存储。这意味着你的JWT可能容易受到XSS(跨站脚本)攻击。恶意JavaScript嵌入在页面上,以读取和破坏Web存储的内容。事实上,很多人主张,由于XSS攻击,一些非常敏感的数据不应该存放在Web存储中。一个非常典型的例子是确保你的JWT不将过于敏感/可信的数据进行编码,例如用户的社会安全号码。

最初,我提到JWT可以存储在cookie中。事实上,JWT在许多情况下被存储为cookie,并且cookies很容易受到CSRF(跨站请求伪造)攻击。预防CSRF攻击的许多方法之一是确保你的cookie只能由你的域访问。作为开发人员,不管是否使用JWT,确保必要的CSRF保护措施到位以避免这些攻击。

现在,JWT和session ID也会暴露于未经防范的重放攻击。建立适合系统的重放防范技术,完全取决于开发者。解决这个问题的一个方法是确保JWT具有短期过期时间。虽然这种技术并不能完全解决问题。然而,解决这个挑战的其他替代方案是将JWT发布到特定的IP地址并使用浏览器指纹。

注意:使用HTTPS / SSL确保你的Cookie和JWT在客户端和服务器传输期间默认加密。这有助于避免中间人攻击!

RESTful API服务

现代应用程序的常见模式是从RESTful API查询使用JSON数据。目前大多数应用程序都有RESTful API供其他开发人员或应用程序使用。由API提供的数据具有几个明显的优点,其中之一就是这些数据可以被多个应用程序使用。在这种情况下,传统的使用session和Cookie的方法在用户认证方面效果不佳,因为它们将状态引入到应用程序中。

RESTful API的原则之一是它应该是无状态的,这意味着当发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。保持API无状态,不产生附加影响,意味着维护和调试变得更加容易。

另一个挑战是,由一个服务器提供API,而实际应用程序从另一个服务器调用它的模式是很常见的。为了实现这一点,我们需要启用跨域资源共享(CORS)。Cookie只能用于其发起的域,相对于应用程序,对不同域的API来说,帮助不大。在这种情况下使用JWT进行身份验证可以确保RESTful API是无状态的,你也不用担心API或应用程序由谁提供服务。

性能

当从客户端向服务器发出请求时,如果大量数据在JWT内进行编码,则每个HTTP请求都会产生大量的开销。编码时,JWT的大小将是SESSION ID(标识符)的几倍,从而在每个HTTP请求中,JWT比SESSION ID增加更多的开销。

 

实效性

JWT是一种无状态身份验证机制,因为用户状态永远不会保存在服务器内存中。 由于JWT是独立的,所有必要的信息都在那里,所以减少了多次查询数据库的需求。

 

此外,无状态JWT的实效性相比session太差,只有等到过期才可销毁,而session则可手动销毁。

例如有个这种场景,如果JWT中存储有权限相关信息,比如当前角色为 admin,但是由于JWT所有者滥用自身权利,高级管理员将权利滥用者的角色降为 user。但是由于 JWT 无法实时刷新,必需要等到 JWT 过期,强制重新登录时,高级管理员的设置才能生效。

或者是用户发现账号被异地登录,然后修改密码,此时token还未过期,异地的账号一样可以进行操作包括修改密码。

但这种场景也不是没有办法解决,解决办法就是将JWT生成的token存入到redis或者数据库中,当用户登出或作出其他想要让token失效的举动,可通过删除token在数据库或者redis里面的对应关系来解决这个问题。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch(4)-模型保存-载入-eval()

模型保存与提取1. 整个模型 保存-载入2. 仅模型参数 保存-载入3. GPU/CPU模型保存与导入4. net.eval()--固定模型随机项神经网络模型在线训练完之后需要保存下来,以便下次使用时可以直接导入已经训练好的模型。pytorch 提供两种方式保存模型:方式1:保存整…

大数据学习(08)--Hadoop中的数据仓库Hive

文章目录目录1.什么是数据仓库?1.1数据仓库概念1.2传统数据仓库面临的挑战1.3 Hive介绍1.4 Hive与传统数据库的对比1.5 Hive在企业中的部署与应用2.Hive系统架构3.Hive工作原理3.1 SQL转换为MapReduce作业的基本原理3.2 Hive中SQL查询转换MapReduce作业的过程4.Hive…

dubbo知识点总结 持续更新

Dubbo 支持哪些协议,每种协议的应用场景,优缺点?  dubbo: 单一长连接和 NIO 异步通讯,适合大并发小数据量的服务调用, 以及消费者远大于提供者。传输协议 TCP,异步,Hessian 序列化…

使用Linux auto Makefile自动生成的运行步骤

首先创建一个 Linux Makefile.am.这一步是创建Linux Makefile很重要的一步,automake要用的脚本配置文件是Linux Makefile.am,用户需要自己创建相应的文件。之后,automake工具转换成Linux Makefile.in。AD: 在向大家详细介绍Linux …

无限踩坑系列(6)-mySQL数据库链接错误

mySQL数据库链接错误错误1错误2长链接短连接应用场景需要一直访问mySQL数据库,遇到如下错误:错误1 释放已经释放的数据库链接conn.,或者,操作已经释放的数据库链接conn.或者失去链接后再操作数据库都可能会报这个错误 aise err.I…

初探函数式编程和面对对象式编程

文章目录目录1.函数式编程和面向对象编程概念1.1 函数式编程1.2 面向对象编程2.函数式编程和面向对象编程的优缺点2.1 函数式编程优点缺点2.2 面对对象编程优点缺点3.为什么在并行计算中函数式编程比较好3.1 什么是并行计算3.2 函数式编程兴起原因目录 1.函数式编程和面向对象…

linux常用解压和压缩文件的命令

linux常用解压和压缩文件的命令 .tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gunzip FileN…

Python外(4)-读写mat文件

读写mat文件1.读取2.写入.mat 是matlab中数据存储的标准格式,Python中能够通过库scipy读取和保存。导入scipy库 from scipy import io 1.读取 io.loadmat(file_name, mdictNone, appendmatTrue, **kwargs) 简便方式: io.loadmat(file_name) append mat–…

Linux下的xml文件的创建

创建一个xml文档流程如下: l 用xmlNewDoc函数创建一个文档指针doc; l 用xmlNewNode函数创建一个节点指针root_node; l 用xmlDocSetRootElement将root_node设置为doc的根结点; l 给root_node添加一系列的子节点&#x…

压力测试http_load 通过修改配置测试https协议成功了。

到http://www.acme.com/software/http_load/ 下载http_load ,安装也很简单直接make;make instlall 就行。 如果你需要测试https,你必须将 Makefile中 # CONFIGURE: If you want to compile in support for https, uncomment these # definitions. You w…

面向对象设计与分析40讲(16)静态工厂方法模式

前面我们介绍了简单工厂模式,在创建对象前,我们需要先创建工厂,然后再通过工厂去创建产品。 如果将工厂的创建方法static化,那么无需创建工厂即可通过静态方法直接调用的方式创建产品: // 工厂类,定义了静…

搜索详解

搜索 一.dfs和bfs简介 深度优先遍历(dfs) 本质: 遍历每一个点。 遍历流程: 从起点开始,在其一条分支上一条路走到黑,走不通了就往回走,只要当前有分支就继续往下走,直到将所有的点遍历一遍。 剪枝&a…

Python外(5)-for-enumerate()-zip()

for循环小技巧技巧1:enumerate()技巧2:打包两个可遍历数据,一起循环-zip()技巧1:enumerate() 在使用pytorch训练网络的过程中,官方教程给出了 for i, data in enumerate(trainloader, 0): 这涉及到enumerate函数的使用…

特征工程总结

目录1 特征工程是什么? 2 数据预处理   2.1 无量纲化     2.1.1 标准化     2.1.2 区间缩放法     2.1.3 标准化与归一化的区别   2.2 对定量特征二值化   2.3 对定性特征哑编码   2.4 缺失值计算   2.5 数据变换 3 特征选择   3.1 Filter …

Jmeter测试并发https请求成功了

Jmeter2.4 如何测试多个并发https请求,终于成功了借此机会分享给大家 首先要安装jmeter2.4版本的,而且不建议大家使用badboy,因为这存在兼容性问题。对于安装,我就不讲了,我就说说如何测试https,想必大家都…

关系数据库——sql基础1定义

关系数据库标准语言SQL 基本概念 SQL语言是一个功能极强的关系数据库语言。同时也是一种介于关系代数与关系演算之间的结构化查询语言(Structured Query Language),其功能包括数据定义、数据查询、数据操纵和数据控制。 SQL的特点&#xff…

libcurl编程

一、curl简介 curl是一个利用URL语法在命令行方式下工作的文件传输工具。它支持的协议有:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。curl同样支持HTTPS认证,HTTP POST方法, HTTP PUT方法, FTP上传, kerberos认证, HTTP上传, 代理服…

大数据学习(09)--Hadoop2.0介绍

文章目录目录1.Hadoop的发展与优化1.1 Hadoop1.0 的不足与局限1.2 Hadoop2.0 的改进与提升2.HDFS2.0 的新特性2.1 HDFS HA2.2 HDFS Federation3. 新一代的资源管理器YARN3.1 MapReduce1.0 缺陷3.2 YARN的设计思路3.3 YARN 体系结构3.4 YARN工作流程3.5 YARN框架与MapReduce1.0框…

Java多线程常用方法

start()与run() start() 启动线程并执行相应的run()方法 run() 子线程要执行的代码放入run()方法 getName()和setName() getName() 获取此线程的名字 setName() 设置此线程的名字 isAlive() 是判断当前线程是否处于活动状态。活动状态就是已经启动尚未终止。 curren…

MachineLearning(2)-图像分类常用数据集

图像分类常用数据集1 CIFAR-102.MNIST3.STL_104.Imagenet5.L-Sun6.caltech-101在训练神经网络进行图像识别分类时,常会用到一些通用的数据集合。利用这些数据集合可以对比不同模型的性能差异。下文整理常用的图片数据集合(持续更新中)。基本信息对比表格…