Web应用登录验证的几种方式

一、Session+Cookie登录

传统的session+cookie登录是一种有状态 的登录

1、传统的session+cookie 流程

在这里插入图片描述

  • 浏览器登录发送账号和密码,服务端查找数据库验证用户
  • 验证成功后,服务端把用户状态(登录状态,角色,权限等信息)存为Session,生成一个SessionId
  • 通过接口将SessionId返回到浏览器,表示用户验证成功,登录完成。浏览器将SessionId存在cookie中
  • 此后浏览器再请求业务接口,服务端发送http请求,并且会将cookie一起发送到服务端
  • 服务端从cookie中拿到SessionID(如果没有SessionID就是第一次登录),和session中的数据进行比对,比对成功,并且有访问权限,就允许访问,否则就访问失败。

2、cookie

cookie是前端存储的一种,但相比于localStorage 等其他方式,借助HTTP头、浏览器能力,cookie可以做到前端无感知。一般过程是这样的:

  • 在提供标记的接口,通过HTTP返回头的Set-Cookie字段,直接“种”到浏览器上
  • 浏览器发起请求时,会自动把cookie通过HTTP请求头的cookie字段,带给接口

cookie是维持HTTP请求状态的基石,是最便捷的维持HTTP请求状态 的方式。

3、Session

Session的具体内容都是存储在服务端,只是给客户端一个SessionId存在cookie。Session的存储方式有:

  • Redis:推荐用Redis存储,以key-value形式存,刚好符号sessionId-sessionData的场景,访问更快
  • 内存:直接放到变量里,一旦服务重启就没有了
  • 数据库:存在磁盘里,性能不高

Session的分布式问题

通常服务端是集群,而用户请求会走负载均衡,不一定就能请求到登录时的服务端。一旦用户后续接口请求到的机器和之前登录请求的机器不一致,或者登录请求的机器宕机了,session就没用了

解决方式:

所有用户的session集中存储,我们可以用独立的Redis或者普通数据库(推荐是Redis)或者消息队列 ,这就是分布式session:

  • 当用户第一次访问应用时,应用会为用户生成一个唯一的会话标识符(session ID),并将该标识符返回给用户
  • 当用户发送后续请求时,会将会话标识符作为请求的一部分发送回服务器。服务器可以利用该会话标识符来识别用户,并获取保存在分布式存储中的会话状态
  • 分布式存储可以是数据库、缓存、消息队列等,它们可以在多个应用服务器之间共享数据。当一个应用服务器接收到请求时,它可以根据会话标识符查询分布式存储,获取用户的会话状态,并进行相应的处理。

4、缺点:

  • 随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高

  • session存储在服务端,如果用户很多的话,服务端保存大量数据,增加服务端的压力

  • 服务从单服务到多服务会面临session共享问题,要考虑分布式的问题

二、token+cookie

在这里插入图片描述

流程

  • 用户登录:用户使用用户名和密码发送登录请求到服务器。服务器验证用户的身份信息,并验证成功后生成一个唯一的令牌(token)。
  • 令牌生成:服务器生成一个包含用户身份验证信息的令牌,并将其返回给客户端 。令牌通常是一个加密的字符串,其中包含了用户的身份信息、授权信息和有效期 等。
  • 令牌存储:服务器将生成的令牌存储在服务器端的缓存或数据库 中,以便后续验证和访问控制。
  • 令牌传递:客户端将接收到的令牌存储在本地,通常可以使用Cookie或LocalStorage 等技术来存储。
  • 请求验证:当客户端发送后续请求到服务器时,需要将令牌放在请求中的请求头、参数或Cookie中,以便服务器进行验证。
  • 令牌验证:服务器接收到请求后,从请求中获取令牌,并与服务器存储的令牌进行比较和验证 。验证包括检查令牌的有效性、合法性以及是否过期等。
  • 授权访问:如果令牌验证通过,服务器会根据令牌中的身份信息进行授权验证,以确定用户是否有权限进行请求的操作。
  • 响应返回:服务器根据验证和授权结果返回相应的响应结果给客户端。

优点

可以隐藏真实数据,避免明文传输。ie里存的是一个32位的uuid

使用于分布式/微服务,解决session共享问题

安全系数高

缺点

存在redis,必须依赖服务器,会占用服务器的资源

效率较低,不过比起传统的session+cookie好多了

三、JWT实现无状态登录

JWT全程是 JSON WEB TOKEN,JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息 ,也可以增加一些额外的其他业务逻辑所必须的声明信息,该token也可以直接被用于认证,也可被加密

JWT的组成部分

  • Header:头,记录令牌类型、签名算法等
  • Payload:有效载荷,携带一些用户信息
  • Signature:签名,防止token被篡权,保证安全性。这个签名由头部和有效负载的Base64编码字符串以及使用指定算法加密的秘密密钥组成。

使用JWT登录过程:

  • 用户提供用户名和密码进行认证。在认证成功后,服务器会生成一个JWT,在其中包含用户的一些身份信息,并使用秘钥 对其进行签名。

  • 服务器将生成的JWT返回给客户端。客户端通常将JWT存储在本地,例如在 localStorage 或者cookie中。

  • 客户端在后续的请求中,在请求的头部或者其他合适的位置添加JWT作为身份验证凭证。一般使用Authorization头部

  • 服务器在接收到请求时,会验证JWT的有效性以及签名。

    在进行签名验证时,需要使用之前生成JWT时使用的相同的秘钥 ,否则将无法正确验证签名,导致JWT无效;

    服务端会检查JWT的各种声明和标准字段,如签发人(issuer)、受众人(audience)、过期时间(expiration time)等。根据业务需求,服务端可以自行定义额外的声明字段。

  • 如果验证通过,表示用户是合法的,并且可以使用JWT中包含的信息来进行身份验证和授权。

优点

  • 实现无状态的认证机制,服务端不需要存储用户的会话信息,只需要校验JWT的合法性即可,减轻服务端的压力
  • JWT可以带有自定义的信息,使得身份验证非常灵活 ,可自行定制所需的信息
  • JWT被签名后,任何篡改都可以被检测到,提供了一定的安全性

缺点

  • 建议不要放敏感数据,因为JWT是一种基于编码的token,使用base64进行编码,而不是加密 ,虽然JWT的签名可以确保token在传输过程中没有被篡改,但是无法保证token的内容不被解码和泄露 ;敏感数据应该存储在安全的服务器端,并仅在需要时通过安全的传输方式在服务端进行处理
  • JWT一旦生成,无法吊销令牌,只能等待令牌自身过期 。所以需要注意的是,JWT的有效期应该设置合理,限制JWT的使用时间,并在过期后重新认证获取新的令牌
  • 令牌长度与其包含用户信息多少正相关,传输开销较大

JWT如何保证不被篡改?

JWT使用签名 来防止被篡改。在生成JWT时,使用一个密钥对JWT的头部和有效负载进行签名。当服务端接收到JWT时,首先会对JWT进行解码,然后使用相同的密钥对解码后的JWT的头部和有效负载重新进行签名 。然后,将重新计算的签名与原始JWT中的签名进行比较。如果重新计算的签名与原始JWT中的签名不一致,说明JWT已被篡改,验证失败

通过使用签名来验证JWT的完整性,可以有效地防止JWT被篡改。任何对JWT进行篡改的尝试都会被服务端检测到。同时,由于JWT中包含了签名算法和秘密密钥,攻击者无法伪造一个合法的签名。需要注意的是,服务端验证JWT时,必须使用与生成JWT时相同的秘密密钥来进行签名验证,否则验证会失败。同时,为了增强安全性,应该选择足够强大的签名算法和秘密密钥,以防止密钥泄露和暴力破解的攻击

四、单点登录

当业务线越来也多,就会有更多业务系统分散到不同域名下(不同的系统),就需要(一次登录,全线通用)的能力,这就是单点登录。

1、“虚假的单点登录”,使主域名相同

我们知道,cookie是有限制的,这个限制就是cookie的域(通常对应网站的域名),浏览器发送http请求时会自动携带与该域匹配的cookie,而不是所有cookie

因此,我们可以将web应用群中所有子系统的域名统一在一个顶级域名下,采用同域名共享cookie的方式。这样也能实现一次登录,全线通用。

但是共享cookie的方式存在众多局限:

  • 所有的子系统域名要统一;

  • 应用群各系统使用的技术要相同,并且共享cookie的方式是无法实现跨语言技术平台登录的

2、“真实”的单点登录

当主域名不同时,实现一次登录,全线使用,这才是真正的单点登录。在这种场景下,我们需要独立的认证服务,通常被称为 SSO(Single Sign On)

在这里插入图片描述

  • 当用户访问A系统,没有登录凭证(ticket),A系统让它重定向到SSO
  • 用户没有在SSO登录,SSO系统下就没有凭证(这个和ticket不是一个东西),用户输入账号和密码进行登录
  • SSO校验账号密码成功,通过接口返回,做两件事:一在SSO系统种下凭证(记录用户的登录状态);二是给用户下发一个ticket
  • 客户端拿到tikcet,保存起来,带着ticket再次访问系统A
  • SSO校验ticket,成功后正常处理业务请求
  • 此时用户第一次访问系统B,没有ticket,B系统让它重定向到SSO
  • 因为用户在SSO登录过,SSO有凭证,不用再次登录,只需要下发ticket
  • 客户端拿到ticket,保存起来,带着ticket请求系统B
  • SSO校验ticket,成功后正常处理业务请求

只有SSO有登录账号密码的功能,其他系统都没有。用户在SSO登录后,SSO就会存储一个用户的登录凭证(这个是全局会话),然后根据重定向过来的地址,颁发要访问的系统的ticket。比如用户是从A系统重定向过来的,就颁发一个A系统的ticket(局部会话),客户端带着这个ticket就可以访问A系统了;当用户要访问B系统时,B系统将它重定向到SSO,已经登录了,所以SSO直接颁发可以访问B系统的ticket,客户端带着这个ticket就可以访问B系统了。这样就实现了一处登录,全线使用

但是这样有一个问题,SSO放回的ticket,浏览器要如何存,因为有很多个域名下,如何才能在下次访问A系统时带上这个ticket?因为浏览器对跨域有严格限制,所以我们需要在A域下保存这个A的ticket

  • 在 SSO 域下,SSO 不是通过接口把 ticket 直接返回,而是通过一个带 code 的 URL 重定向到系统 A 的接口上 ,这个接口通常在 A 向 SSO 注册时约定
  • 浏览器被重定向到 A 域下,带着 code 访问了 A 的 callback 接口,callback 接口通过 code去SSO中 换取 ticket
  • 这个 code 不同于 ticket,code 是一次性的,暴露在 URL 中,只为了传一下换 ticket,换完就失效
  • callback 接口拿到 ticket 后,在**自己的域下 set cookie ** 成功
  • 在后续请求中,浏览器只需要把 cookie 中的 ticket 解析出来,然后去SSO 中 验证就可以了

五、总结

1、HTTP 是无状态的,为了维持前后请求,需要前端存储标记-----cookie

2、cookie 是一种完善的标记方式,通过 HTTP 头或 js 操作,有对应的安全策略,是大多数状态管理方案的基石

3、session 是一种状态管理方案,前端通过 cookie 存储 id,后端存储数据,但后端要处理分布式问题

4、token 是另一种状态管理方案,token 的编码技术,通常基于 base64,或增加加密算法防篡改;jwt 是一种成熟的编码方案,并且JWT实现了无状态登录,相较于传统的有状态登录,更加灵活,解放服务端

5、session 和 token 的对比就是「用不用cookie」和「后端存不存」的对比

6、单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket,各业务系统配合存储和认证 ticket

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

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

相关文章

【python】jupyter notebook导出pdf和pdf不显示中文问题

文章目录 写在前面1. 使用jupyter notebook导出pdf1.1 安装Pandoc1.2 安装MiKTex1.3 示例导出pdf 2. 中文显示问题2.1 显示中文问题示例2.2 解决办法1:修改tex2.3 解决办法2:修改内置文件 写在前面 使用jupyter notebook导出pdf时,出现了一些…

31、springboot 配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口

配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口 ★ 设置HTTP服务端口: - server.port或者SERVER_PORT环境变量——总结来说,其实就是要配置server.port外部配置属性。▲ 同样遵守如下优先级: 这些都是外部配置源&#x…

Win 11 电脑的 Win + E 快捷键失效

报的错误信息如下: 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在”默认应用设置"页面中创建关联。 报错原因:系统注册表被改写了导致的出错 解决办法: 1、首先,按键盘上…

python编程环境使用技巧2-python环境迁移

Python环境迁移步骤 将Python环境从一个计算机迁移到另一个计算机可以按照以下步骤进行: 1-备份环境: 在源计算机上,使用pip工具备份当前Python环境的包列表到一个文本文件。在命令行终端中执行以下命令: pip freeze > requi…

【韩顺平 零基础30天学会Java】数组、排序和查找(2days)

数组、排序、查找和多维数组 数组可以存放多个同一类型的数据。数组也是一种数据类 型,是引用数据类型。 定义一个数组 double[] hens {3,5,1,3.4,2,50} 遍历数组得到数组所有元素的和 hens[下标],下标是从0开始编号的。 可以通过数组名.lenght得到数组…

【数据库】使用ShardingSphere+Mybatis-Plus实现读写分离

书接上回:数据库调优方案中数据库主从复制,如何实现读写分离 ShardingSphere 实现读写分离的方式是通过配置数据源的方式,使得应用程序可以在执行读操作和写操作时分别访问不同的数据库实例。这样可以将读取操作分发到多个从库(从…

详细手机代理IP配置

嗨,亲爱的朋友们!作为一家代理产品供应商,我知道有很多小伙伴在使用手机进行网络爬虫和数据采集时,常常会遇到一些IP限制的问题。别担心!今天我要给大家分享一下手机IP代理的设置方法,让你们轻松应对这些限…

vue2 路由入门

一、单页应用程序介绍 1.概念 单页应用程序:SPA【Single Page Application】是指所有的功能都在一个html页面上实现 2.具体示例 单页应用网站: 网易云音乐 https://music.163.com/ 多页应用网站:京东 https://jd.com/ 3.单页应用 VS 多页…

PostgreSQL命令行工具psql常用命令

1. 概述 通常情况下操作数据库使用图形化客户端工具,在实际工作中,生产环境是不允许直接连接数据库主机,只能在跳板机上登录到Linux服务器才能连接数据库服务器,此时就需要使用到命令行工具。psql是PostgreSQL中的一个命令行交互…

一百六十四、Kettle——Linux上脚本运行kettle的转换任务(Linux本地、Linux资源库)

一、目的 在kettle的转换任务以及共享资源库、Carte服务创建好后,需要对kettle的转换任务用海豚调度器进行调度,调度的前提的写好脚本。所以,这篇博客首先介绍在Linux上脚本运行kettle的转换任务 二、前提准备 (一)…

【PHP】echo 输出数组报Array to string conversion解决办法

代码&#xff1a; <?PHP echo "Hello World!";$demoName array("kexuexiong","xiong");echo "<pre>";var_dump($demoName);echo $demoName; print_r($demoName);echo "</pre>"; ?>输出结果&#xff1…

土豆叶病害识别(图像连续识别和视频识别)

效果视频&#xff1a;土豆叶病害识别&#xff08;Python代码&#xff0c;pyTorch框架&#xff0c;视频识别&#xff09;_哔哩哔哩_bilibili 代码运行要求&#xff1a;Torch库>1.13.1&#xff0c;其它库无版本要求 1..土豆叶数据集主要包好三种类别&#xff08;Early_Blight…

自然语言处理(二):近似训练

近似训练 近似训练&#xff08;Approximate Training&#xff09;是指在机器学习中使用近似的方法来训练模型&#xff0c;以降低计算复杂度或提高训练效率。这种方法通常用于处理大规模数据集或复杂模型&#xff0c;其中精确的训练算法可能过于耗时或计算资源不足。 近似训练…

机器学习理论笔记(二):数据集划分以及模型选择

文章目录 1 前言2 经验误差与过拟合3 训练集与测试集的划分方法3.1 留出法&#xff08;Hold-out&#xff09;3.2 交叉验证法&#xff08;Cross Validation&#xff09;3.3 自助法&#xff08;Bootstrap&#xff09; 4 调参与最终模型5 结语 1 前言 欢迎来到蓝色是天的机器学习…

【springboot】Spring Cache缓存:

文章目录 一、导入Maven依赖&#xff1a;二、实现思路&#xff1a;三、代码开发&#xff1a; 一、导入Maven依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId><…

lnmp架构-mysql

1.MySQL数据库编译 make完之后是这样的 mysql 初始化 所有这种默认不在系统环境中的路径里 就这样加 这样就可以直接调用 不用输入路径调用 2.初始化 重置密码 3.mysql主从复制 配置master 配置slave 当master 端中还没有插入数据时 在server2 上配slave 此时master 还没进…

2.文章复现《热电联产系统在区域综合能源系统中的定容选址研究》(附matlab程序)

0.代码链接 1.简述 光热发电是大规模利用太阳能的新兴方式&#xff0c;其储热系 统能够调节光热电站的出力特性&#xff0c;进而缓解光热电站并网带来的火电机组调峰问题。合理配置光热电站储热容量&#xff0c;能够 有效降低火电机组调峰成本。该文提出一种光热电站储热容 量配…

HLS实现CORDIC算法计算正余弦并上板验证

硬件&#xff1a;ZYNQ7010 软件&#xff1a;MATLAB 2019b、Vivado 2017.4、HLS 2017.4、System Generator 2017.4 1、CORDIC算法计算正余弦 CORDIC算法详细分析网上有很多资料&#xff0c;它的原理是用一系列旋转去逼近目标角度&#xff0c;这一系列旋转的角度为 θ a r c t…

Unity中实现获取InputField选中的文字

一&#xff1a;前言 获取到选中的文字&#xff1a;哈哈 二&#xff1a;实现 UGUI的InputField提供了selectionAnchorPosition和selectionFocusPosition&#xff0c;开始选择时的光标下标和当前光标下标 using UnityEngine; using UnityEngine.EventSystems; using UnityEngin…

蓝蓝设计ui设计公司作品案例-中节能现金流抗压测试软件交互及界面设计

中国节能是以节能环保为主业的中央企业。中国节能以生态文明建设为己任&#xff0c;长期致力于让天更蓝、山更绿、水更清&#xff0c;让生活更美好。经过多年发展&#xff0c;中国节能已构建起以节能、环保、清洁能源、健康和节能环保综合服务为主业的41产业格局&#xff0c;成…