几种用户鉴权的方式对比

几种用户鉴权的方式对比

最近也要准备秋招,刚好整理下前后端一般采用的几种鉴权方式。

一、传统用户鉴权

传统用户鉴权
详细步骤
  1. 用户登录
    • 用户通过前端提交用户名和密码到后端服务器,后端服务器验证用户名和密码是否正确。
    • 如果验证成功,后端生成一个 session(会话),并将其保存在服务器端。
  2. Session存储
    • 后端会将该用户的会话信息保存在服务器的内存或数据库中,或者通过 Redis 等缓存系统,每个用户的会话都会与一个唯一的 Session ID 绑定,并通过 Cookie 发送到浏览器。
    • 浏览器会将 Session ID 存储在 Cookie 中,每次请求时,都会自动将该 Cookie 附带到请求头中发送给服务器。
  3. Session验证
    • 每次用户发起请求时,浏览器都会携带上次登录时存储的 Session ID,后端服务器根据请求中的 Session ID 来查找对应的会话信息,验证用户是否已登录。
    • 如果 Session 存在且有效,则认为用户已经登录,可以继续访问相关资源;如果 Session 不存在或失效,则需要用户重新登录。
  4. 用户登出
    • 用户主动登出时,前端会向后端发送请求,后端会清除该用户的 Session
    • 服务器会删除该 Session 数据,浏览器中的 Session ID 也会失效。
优势
  • 架构清晰,易于理解:传统的 Session 认证非常直接,登录时会话存储简单,验证方式清晰。
  • 易于实现:适合小型应用,尤其是没有复杂分布式需求的场景。
  • 安全性相对较高:会话存储在服务器端,不容易受到 XSS 攻击的影响。
  • 不需要存储敏感信息在客户端:用户的敏感信息(如密码)不会直接暴露在客户端。
缺点
  1. 不适用于集群环境
    • 当应用部署到多个服务器时,每台服务器的 Session 数据是独立的,因此无法在不同服务器间共享 Session。在集群中,用户切换服务器时,可能会导致会话丢失(例如,用户登录在服务器 A 上,切换到服务器 B 后发现 Session 失效)。
    • 解决这个问题通常需要使用 分布式缓存(如 Redis) 来存储 Session,保证集群环境下 Session 的共享。
  2. “一处登录,处处登录”难以实现
    • 传统的 Session 机制通常是单一服务器的,会话仅在该服务器有效。若多个服务器部署,无法保证用户在多个地方登录时的统一状态。
    • 这种需求可以通过 单点登录(SSO) 或通过共享的会话存储解决,但实现起来会复杂一些。
  3. 性能问题
    • 会话信息的存储(特别是存储在内存中)可能会占用大量资源。如果用户量非常大,服务器的内存可能会成为瓶颈。
    • 尤其在高并发场景下,频繁的 Session 查找和存取可能影响性能。
  4. 会话管理复杂
    • 需要手动处理用户的会话过期时间,维护 Session 的有效性。
    • 如果没有合理的过期机制,Session 数据可能会占用大量内存,造成资源浪费。
  5. 前端依赖 Cookie
    • 传统的 Session 鉴权依赖于浏览器的 Cookie 机制。如果用户禁用了 Cookie 或使用了特殊的浏览器配置(如隐私模式),则会话管理会失败。

适用场景
  • 小型应用:对于小型的单服务器应用,传统的 Session 认证方式较为简单且有效。
  • 不需要高度分布式的应用:如果应用没有分布式部署的需求,使用传统的 Session 鉴权能够快速实现。
  • 用户量较小的应用:用户量较少时,Session 数据管理较为简单,适合传统的方式。

代码实现举例
后端
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpSession;@Controller
public class UserController {private final UserService authService;public UserController(UserService authService) {this.authService = authService;}// 登录@PostMapping("/login")public String login(@RequestParam("username") String username,@RequestParam("password") String password,HttpSession session) {if (authService.isValidUser(username, password)) {session.setAttribute("username", username);  // 设置Sessionreturn 用户相关信息;} else {return "error"; }}// 登出@GetMapping("/logout")public String logout(HttpSession session) {session.invalidate();  // 销毁session}
}
在浏览器中查看

打开浏览器的开发者工具,在如下位置即可查看

image-20250203114711197

二、JWT(JSON Web Token)认证方式

JWT 的优点是灵活性高、无状态、易于扩展,但也有一些安全隐患,例如,如果密钥管理不当,JWT 会容易受到攻击(如签名泄露)。

JWT原理和数据结构

JWT是一种用于在网络应用环境中传递声明的开放标准(RFC 7519)。它通过一个 URL 安全的方式传递声明(如用户信息、权限等)。JWT 的主要作用是为了验证身份并安全地在客户端与服务器之间传递信息。

JWT 的基本原理是使用 数字签名 来验证发送方的身份和信息的完整性。JWT 主要由三部分组成:

  1. Header(头部)
  2. Payload(负载)
  3. Signature(签名)

这三部分以点(.)连接,形成最终的 JWT 字符串:
<header>.<payload>.<signature>

1. Header(头部)

JWT 的头部通常由两部分组成:

  • alg(算法): 签名算法,如 HS256(HMAC SHA256)或者 RS256(RSA SHA256)等。
  • typ(类型): 该字段通常是 JWT,标识该对象是一个 JWT。
示例(Header):
{"alg": "HS256","typ": "JWT"
}

image-20250203131817138

编码过程:
Header 会进行 Base64Url 编码,得到编码后的字符串部分。

2. Payload(负载)

JWT 的负载部分存储了声明(Claims)。声明可以是关于实体(通常是用户)和其他数据的任何信息。负载并没有加密,所以可以直接读取。然而,为了保密性,敏感数据不应存放在 payload 中。

JWT 中的声明主要有三类:

  • 注册声明(Registered Claims):这些是预定义的字段,但不是必须的。常用的有:
    • sub:主题(通常是用户 ID)
    • iss:发行者(Issuer)
    • exp:过期时间(Expiration Time)
    • iat:签发时间(Issued At)
    • aud:观众(Audience)
    • nbf:生效时间(Not Before)
  • 公共声明(Public Claims):可以自定义,也可以使用已注册的名字。
  • 私有声明(Private Claims):应用之间共享的自定义声明,通常为了传递额外的信息。

image-20250203131921622

示例(Payload):
{"sub": "1234567890","name": "John Doe","iat": 1516239022
}

编码过程:
类似于 Header,Payload 部分也需要进行 Base64Url 编码,得到编码后的字符串部分。

3. Signature(签名)

签名是为了验证 JWT 的数据是否被篡改,并且确保消息的发送者是可信的。签名是根据以下几个部分计算得出的:

  • 编码后的 Header
  • 编码后的 Payload
  • 一个密钥(对称算法)或者公私密钥对(非对称算法)

签名的生成过程:使用头部的 alg 指定的算法(例如 HS256)来签名。

image-20250203132036246

示例(Signature):

假设使用 HMAC SHA256 算法(HS256),密钥为 jieyu123456jieyu,则签名计算过程如下:

HMACSHA256(Base64UrlEncode(header) + "." + Base64UrlEncode(payload),secret)

编码过程:
生成签名后,它会通过 Base64Url 编码,然后得到 JWT 的签名部分。

最终的 JWT 结构:

image-20250203132115347

最终的 JWT 是由三部分组成,且通过点(.)连接:

  • HeaderBase64Url(Header)
  • PayloadBase64Url(Payload)
  • SignatureBase64Url(Signature)

JWT 的工作流程

  1. 用户登录:当用户登录时,服务器验证用户的身份,并生成一个 JWT 令牌返回给客户端(通常是浏览器或移动应用)。服务器在生成 JWT 时,使用一个密钥(对称加密)或公私密钥对(非对称加密)进行签名。

  2. 客户端存储 JWT:客户端通常会将 JWT 存储在 localStoragesessionStorage 中,或者通过 HTTP cookie 存储。

  3. 请求授权:在后续的 API 请求中,客户端将 JWT 作为 HTTP 请求头的一部分,使用 Authorization 字段发送到服务器:

    Authorization: Bearer <JWT>
    
  4. 服务器验证:服务器通过验证签名来验证 JWT 的有效性。如果签名有效,并且其他声明(如 exp)也符合要求,服务器会处理请求。否则,拒绝请求并返回 401 未授权。

  5. 过期机制:JWT 通常会有一个过期时间 exp,一旦 JWT 过期,客户端需要重新获取一个新的 JWT。

为什么第三部分要加密:因为第三部分是防止用户篡改鉴定用的,所以不能对外显示

三、OAuth 认证

OAuth 是一种授权协议,它允许第三方应用在不暴露用户凭据(如用户名和密码)的情况下,访问用户在服务提供者上的资源。OAuth 是目前广泛使用的授权框架,尤其是在 Web 应用、移动应用和 API 认证中。OAuth 的核心思想是 授权,而非 认证。认证是验证用户的身份,而授权是允许用户的某些资源被第三方应用访问。OAuth 通过授权流程使得用户可以控制哪些应用可以访问哪些资源。

OAuth 2.0 是一种广泛使用的授权协议,适用于 Web 应用、移动应用、API 授权等场景。它通过访问令牌和授权流程实现了用户资源的安全授权,避免了直接暴露用户名和密码的风险。OAuth 2.0 提供了多种授权模式,适应不同的应用场景。同时,它通过角色和令牌机制,实现了精细化的资源授权和访问控制。在实施 OAuth 时,需关注安全性问题,确保令牌的安全存储、传输以及正确的权限控制。

(官网和网址如下图)

image-20250203171452630


1. OAuth 协议
  • OAuth 1.0 和 OAuth 2.0:OAuth 2.0 是 OAuth 协议的升级版,它相比 OAuth 1.0 更加简洁、灵活,并且得到了广泛的使用。OAuth 2.0 不再使用复杂的加密算法,而是通过访问令牌来实现授权。
  • OAuth 2.0 流程:OAuth 2.0 是以授权码为核心的授权流程,可以支持多种应用场景(Web、移动、桌面等)。

2. OAuth 2.0 流程

OAuth 2.0 流程通常分为以下几个步骤:

  1. 用户请求授权
    • 用户尝试使用第三方应用访问某些资源时,第三方应用会重定向用户到授权服务器,用户在授权服务器上同意授权。
    • 授权请求中会包括:client_id(客户端标识)、redirect_uri(授权回调地址)、response_type(响应类型,通常为“code”)等参数。
  2. 用户授权
    • 用户在授权服务器上进行身份验证,并授权第三方应用访问资源。
  3. 授权码返回
    • 授权服务器在用户授权后,会将一个 授权码(Authorization Code)重定向回客户端应用指定的 redirect_uri
  4. 客户端请求令牌
    • 客户端应用使用授权码和自身的 客户端密钥(Client Secret)向授权服务器请求访问令牌(Access Token)。
    • 请求会通过 HTTPS 发送,通常包括:client_idclient_secretcode(授权码)、redirect_uri 等参数。
  5. 获取访问令牌
    • 如果授权码有效,授权服务器会返回一个 访问令牌(Access Token)和一个 刷新令牌(Refresh Token)。
    • 访问令牌用于后续的资源访问,刷新令牌用于在访问令牌过期时重新获取新的访问令牌。
  6. 资源访问
    • 客户端使用访问令牌访问受保护的资源服务器。访问令牌通常通过 Authorization 请求头以 Bearer 类型传递。

3. OAuth 2.0 的四种授权模式

OAuth 2.0 提供了四种授权流程模式,分别适用于不同的应用场景:

  1. 授权码模式(Authorization Code Flow)

    • 最常用的 OAuth 2.0 授权模式。
    • 适用于 Web 应用和客户端应用,其中客户端应用的安全性较高,能妥善保管客户端密钥。
    • 通过浏览器重定向用户进行授权,并使用授权码交换访问令牌。

    流程

    • 用户授权,获取授权码
    • 客户端用授权码请求访问令牌
    • 获取访问令牌后访问资源
  2. 隐式授权模式(Implicit Flow)

    • 适用于 单页应用(SPA)移动应用,这些应用没有后端服务器,无法安全存储客户端密钥。
    • 访问令牌直接返回给客户端(不使用授权码),因此令牌会直接暴露在客户端,安全性较低,通常用于非机密客户端。

    流程

    • 用户授权,直接返回访问令牌
    • 客户端用令牌访问资源
  3. 资源所有者密码模式(Resource Owner Password Flow)

    • 适用于 可信应用,即用户对客户端完全信任的情况(例如客户端是操作系统应用)。
    • 用户直接提供用户名和密码给客户端应用,客户端用这些凭据请求访问令牌。
    • 安全性较低,一般不推荐在没有必要的情况下使用。

    流程

    • 用户提供用户名和密码
    • 客户端用凭据请求访问令牌
    • 获取访问令牌后访问资源
  4. 客户端凭证模式(Client Credentials Flow)

    • 适用于 服务器与服务器之间的通信,例如后台服务之间的 API 调用。
    • 客户端应用使用其自身的凭证(如客户端 ID 和客户端密钥)向授权服务器请求访问令牌。

    流程

    • 客户端凭证请求访问令牌
    • 获取访问令牌后访问资源

4. OAuth 2.0 的主要角色

OAuth 2.0 协议涉及到四个主要角色:

  1. 资源所有者(Resource Owner)
    • 通常是应用的最终用户,拥有资源的控制权(例如用户的个人信息、照片、文件等)。
    • 用户授权应用访问其受保护的资源。
  2. 客户端(Client)
    • 代表第三方应用的服务,可以是 Web 应用、移动应用、桌面应用等。
    • 客户端向授权服务器请求访问令牌,并使用令牌访问资源服务器。
  3. 授权服务器(Authorization Server)
    • 负责授权客户端应用访问用户资源,并颁发访问令牌。
    • 它通常会验证客户端的身份,确保请求者有权限获取令牌。
  4. 资源服务器(Resource Server)
    • 存储受保护的资源并提供访问接口。
    • 资源服务器验证客户端提供的访问令牌是否合法,如果合法,允许访问资源。

5. OAuth 2.0 的访问令牌和刷新令牌
  • 访问令牌(Access Token)
    • 访问令牌用于授权客户端访问受保护的资源。
    • 令牌通常有有效期,一旦过期需要刷新或重新获取。
  • 刷新令牌(Refresh Token)
    • 刷新令牌是用来获取新的访问令牌的凭证。
    • 它通常在访问令牌过期后使用,而不需要用户重新授权。
    • 刷新令牌一般具有较长的有效期,甚至可以一直有效。

7. OAuth 的常见应用场景
  • 单点登录:OAuth 可以用于多个应用之间的授权和身份验证,解决跨多个系统的用户认证问题。
  • 移动应用授权移动应用可以通过 OAuth 访问第三方服务的资源(如获取社交媒体数据、支付信息等)。
  • API 授权:当需要第三方应用访问某个 API 时,OAuth 可以提供安全的授权机制,确保用户的隐私和安全。

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

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

相关文章

基于springboot+vue的航空散货调度系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

区块链的核心原理:加密算法、共识机制与分布式账本

区块链&#xff08;Blockchain&#xff09;技术自比特币诞生以来&#xff0c;已经从一个单纯的数字货币系统演变为广泛应用于金融、供应链、医疗、政府等多个领域的技术架构。作为一种去中心化的分布式账本技术&#xff0c;区块链的核心原理主要依赖于三个关键组成部分&#xf…

Altium Designer绘制原理图时画斜线的方法

第一步&#xff1a;检查设置是否正确 打开preferences->PCB Editor ->Interactive Routing->Interactive Routing Options->Restrict TO 90/45去掉勾选项&#xff0c;点击OK即可。如下图所示&#xff1a; 然后在划线时&#xff0c;按下shift空格就能够切换划线…

Elasticsearch基本使用详解

文章目录 Elasticsearch基本使用详解一、引言二、环境搭建1、安装 Elasticsearch2、安装 Kibana&#xff08;可选&#xff09; 三、索引操作1、创建索引2、查看索引3、删除索引 四、数据操作1、插入数据2、查询数据&#xff08;1&#xff09;简单查询&#xff08;2&#xff09;…

Intel 与 Yocto 项目的深度融合:全面解析与平台对比

在嵌入式 Linux 领域&#xff0c;Yocto 项目已成为构建定制化 Linux 发行版的事实标准&#xff0c;广泛应用于不同架构的 SoC 平台。Intel 作为 x86 架构的领导者&#xff0c;在 Yocto 生态中投入了大量资源&#xff0c;为其嵌入式处理器、FPGA 和 AI 加速硬件提供了完整的支持…

java命令详解

这里以jdk8为例子&#xff0c;查看默认的垃圾回收器 java -XX:PrintCommandLineFlags -version-XX:UseParallelGC : Parallel Scavenge 和 Parallel Old 组合 -XX:InitialHeapSize268435456 : 初始化堆大小&#xff08;字节&#xff09; -XX:MaxHeapSize4294967296 : 最大堆大…

51单片机看门狗系统

在 STC89C52 单片机中&#xff0c;看门狗控制寄存器的固定地址为 0xE1。此地址由芯片厂商在硬件设计时确定&#xff0c;但是它在头文件中并未给出&#xff0c;因此在使用看门狗系统时需要声明下这个特殊功能寄存器 sfr WDT_CONTR 0xE1; 本案将用一个小灯的工作状况来展示看门…

中间件的概念及基本使用

什么是中间件 中间件是ASP.NET Core的核心组件&#xff0c;MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲&#xff1a;Tomcat、WebLogic、Redis、IIS&#xff1b;狭义上来讲&#xff0c;ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…

Unity实现按键设置功能代码

一、前言 最近在学习unity2D&#xff0c;想做一个横版过关游戏&#xff0c;需要按键设置功能&#xff0c;让用户可以自定义方向键与攻击键等。 自己写了一个&#xff0c;总结如下。 二、界面效果图 这个是一个csv文件&#xff0c;准备第一列是中文按键说明&#xff0c;第二列…

独立开发浏览器插件:案例与启示

浏览器插件&#xff08;Browser Extension&#xff09;作为提升用户浏览体验的重要工具&#xff0c;近年来吸引了许多独立开发者的关注。从广告拦截到生产力工具&#xff0c;再到个性化定制功能&#xff0c;浏览器插件的开发为个人开发者提供了一个低成本、高潜力的创业机会。本…

Deep Sleep 96小时:一场没有硝烟的科技保卫战

2025年1月28日凌晨3点&#xff0c;当大多数人还沉浸在梦乡时&#xff0c;一场没有硝烟的战争悄然打响。代号“Deep Sleep”的服务器突遭海量数据洪流冲击&#xff0c;警报声响彻机房&#xff0c;一场针对中国关键信息基础设施的网络攻击来势汹汹&#xff01; 面对美国发起的这场…

基于STM32景区环境监测系统的设计与实现(论文+源码)

1系统方案设计 根据系统功能的设计要求&#xff0c;展开基于STM32景区环境监测系统设计。如图2.1所示为系统总体设计框图。系统以STM32单片机作为系统主控模块&#xff0c;通过DHT11传感器、MQ传感器、声音传感器实时监测景区环境中的温湿度、空气质量以及噪音数据。系统监测环…

Docker 部署教程jenkins

Docker 部署 jenkins 教程 Jenkins 官方网站 Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;过程。它帮助开发人员自动化构建、测试和部署应用程序&#xff0c;显著提高软件开发的效率和质量…

八、Spring Boot 日志详解

目录 一、日志的用途 二、日志使用 2.1 打印日志 2.1.1 在程序中获取日志对象 2.1.2 使用日志对象打印日志 2.2、日志框架介绍 2.2.1 门面模式(外观模式) 2.2.2 门面模式的实现 2.2.3 SLF4J 框架介绍 2.3 日志格式的说明 2.4 日志级别 2.4.1 日志级别的分类 2.4.2…

25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表

目录 240. 搜索二维矩阵 II题目描述题解 148. 排序链表题目描述题解 240. 搜索二维矩阵 II 点此跳转题目链接 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到…

014-STM32单片机实现矩阵薄膜键盘设计

1.功能说明 本设计主要是利用STM32驱动矩阵薄膜键盘&#xff0c;当按下按键后OLED显示屏上会对应显示当前的按键键值&#xff0c;可以将此设计扩展做成电子秤、超市收银机、计算器等需要多个按键操作的单片机应用。 2.硬件接线 模块管脚STM32单片机管脚矩阵键盘行1PA0矩阵键盘…

将ollama迁移到其他盘(eg:F盘)

文章目录 1.迁移ollama的安装目录2.修改环境变量3.验证 背景&#xff1a;在windows操作系统中进行操作 相关阅读 &#xff1a;本地部署deepseek模型步骤 1.迁移ollama的安装目录 因为ollama默认安装在C盘&#xff0c;所以只能安装好之后再进行手动迁移位置。 # 1.迁移Ollama可…

CMake的QML项目中使用资源文件

Qt6.5的QML项目中&#xff0c;我发现QML引用资源文件并不像QtWidgets项目那样直接。 在QtWidgets的项目中&#xff0c;我们一般是创建.qrc​资源文件&#xff0c;然后创建前缀/new/prefix​&#xff0c;再往该前缀中添加一个图片文件&#xff0c;比如&#xff1a;test.png​。…

SAP HCM 回溯分析

最近总有人问回溯问题&#xff0c;今天把12年总结的笔记在这共享下&#xff1a; 12年开这个图的时候总是不明白是什么原理&#xff0c;教程看N次&#xff0c;网上资料找一大堆&#xff0c;就是不明白原理&#xff0c;后来为搞明白逻辑&#xff0c;按照教材的数据一样做&#xf…

强化学习笔记(5)——PPO

PPO视频课程来源 首先理解采样期望的转换 变量x在p(x)分布下&#xff0c;函数f(x)的期望 等于f(x)乘以对应出现概率p(x)的累加 经过转换后变成 x在q(x)分布下&#xff0c;f(x)*p(x)/q(x) 的期望。 起因是&#xff1a;求最大化回报的期望&#xff0c;所以对ceta求梯度 具体举例…