前端开发中常用的鉴权方式解析与实践要点

简介: 本文深入探讨了前端开发中常用的鉴权方式,包括HTTP基本鉴权、Session-Cookie鉴权、Token验证、JWT(JSON Web Tokens)、单点登录(SSO)和OAuth等。文章首先明确了认证、授权、鉴权和权限控制的概念及关系,随后详细解析每种鉴权方式的工作原理、优缺点及适用场景。例如,HTTP基本鉴权简单但安全性低,适合内部网络;Session-Cookie鉴权易受CSRF攻击,适用于同域Web应用;Token和JWT无状态且扩展性好,适合分布式系统;SSO提升用户体验,适用于多系统统一登录;OAuth安全方便,适合第三方授权接入。

在探讨前端常用的鉴权方式之前,我们先来明晰几个关键概念:认证、授权、鉴权以及权限控制,搞清楚它们之间的关系,能帮助我们更好地理解后续内容。

认证(Identification),是依据声明者独有的识别信息来确认其身份。就好比我们需要用身份证来证明“我就是我”。常见的认证技术涵盖用户的生物学特征,如指纹、语音、眼睛虹膜,还有用户的大数据识别等。

授权(Authorization),在信息安全领域指资源所有者委派执行者,并赋予执行者特定范围的资源操作权限。在现实生活中,像银行卡(由银行派发)、门禁卡(由物业管理处派发)、钥匙(由房东派发),这些都是授权的体现;在互联网领域,web服务器的session机制、web浏览器的cookie机制、颁发授权令牌(token)等,均属于授权机制。

鉴权(Authentication),在信息安全领域,是对声明者所声明的身份权利的真实性进行鉴别确认。从授权的角度出发,更容易理解鉴权,授权和鉴权是上下游匹配的关系,先有授权,才有鉴权。在现实生活里,门禁卡需要通过门禁卡识别器验证,银行卡需要通过银行卡识别器验证;在互联网领域,则是校验session/cookie/token的合法性与有效性。鉴权起着承上启下的作用,它接收授权的输出,校验其真实性后获取权限(permission),为下一步的权限控制做准备。

权限控制(Access/Permission Control),是将可执行的操作定义为权限列表,然后判断操作是否被允许或禁止。可以从权限和控制两方面来理解,权限是抽象的逻辑概念,控制是具体的实现方式。例如在现实生活中,有的门禁卡拥有开公司所有门的权限,有的门禁卡因具备管理员角色权限,所以能开公司所有的门;在互联网领域,通过web后端服务控制接口访问,决定是否允许访问请求。

认证、授权、鉴权和权限控制这四个环节,通常是前后依次发生、呈上下游关系的。不过,在某些场景下它们也会同时出现。比如使用门禁卡开门,认证、授权、鉴权、权限控制四个环节瞬间同时完成;用户登录网站时,在使用用户名和密码登录的那一刻,认证和授权一同完成,而鉴权和权限控制则在后续的请求访问中,如选购物品或支付时发生。

接下来,我们详细探讨前端常用的鉴权方式。

HTTP基本鉴权

在HTTP中,基本认证方案(Basic Access Authentication)允许客户端(一般指网页浏览器)在请求时,通过用户提供用户名和密码的方式来验证用户身份。不过,如今几乎所有的线上网站都不会采用该认证方案,了解即可。

认证流程图及步骤解析

  1. 客户端(如浏览器)向服务器请求受限的列表数据或资源,例如:
GET /list/ HTTP/1.1 
Host: www.baidu.com 
Authorization: Basic aHR0cHdhdGNoOmY=
  1. 服务器告知客户端该资源在安全区(如baidu.com)内,属于受限资源,需要进行基本认证,并向客户端返回401状态码(Unauthorized未被授权的),同时附带一个认证域“www - Authenticate: Basic realm = ”baidu.com””要求进行身份验证,其中“Basic”是验证模式,“realm = "baidu.com"”表明客户端需输入该安全域的用户名和密码,而非其他域的,如下所示:
HTTP/1.1 401 Unauthorized 
www - Authenticate: Basic realm = "baidu.com"
  1. 客户端收到要求后,若为浏览器,会自动弹出一个弹窗让用户输入用户名和密码。输入完毕后,客户端将用户名及密码以Base64加密方式发送给服务器,传送格式如下(其中Basic内容为:用户名:密码的ase64形式):
GET /list/ HTTP/1.1 
Authorization: Basic Ksid2FuZzp3YW5n==
  1. 服务器校验“Authorization”字段中的用户名和密码,若正确,则返回客户端所需资源:
HTTP/1.1 OK...

优点:该方式较为简单,且基本所有流行的浏览器都支持。

缺点

  • 不安全:基于HTTP传输,数据几乎是裸奔的。虽使用Base64编码,但很容易被解码。即便认证内容无法解码为原始用户名和密码,恶意用户获取认证内容后,也可利用其不断向服务器发起请求,即重放攻击。
  • 无法主动注销:HTTP协议未提供清除浏览器中Basic认证信息的机制,除非关闭标签页或浏览器、清除历史记录。

使用场景:适用于内部网络,或者对安全要求不高的网络。

Session - Cookie鉴权

Session - Cookie认证利用服务端的Session(会话)和浏览器(客户端)的Cookie来实现前后端通信认证。在理解这种方式前,我们先简单了解一下Cookie和Session。

HTTP是无状态协议,对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息。为了让服务器区分不同的客户端,就需要主动维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器,而这个状态可以通过Cookie来实现。Cookie是由服务器生成,发送给浏览器并存储在浏览器中的一小段数据,下次浏览器向同一服务器发送请求时,会自动带上该Cookie。

Session则是服务器端为每个客户端会话创建的一个对象,用于存储与该客户端相关的信息。可以说Session本质上也是一种特殊的Cookie,只不过它是包含会话ID的Cookie。

鉴权步骤如下

  1. 用户在浏览器将用户凭证(如通过表单提交的账号密码)发送到服务器。
  2. 服务器认证通过后,在服务器内部存储一个包含有效期的会话ID,同时把该会话ID包装成Cookie发送给浏览器。
  3. 浏览器存储该Session,并且每次请求网站时都会携带该Session。
  4. 服务器收到请求后,能成功匹配发来的Session会话ID,则表示认证成功。

优点

  • 广泛支持:几乎所有的浏览器都支持Cookie和Session机制,兼容性好。
  • 简单易用:实现相对简单,对于一些小型应用或者对安全性要求不是特别高的场景,是一种较为常用的鉴权方式。

缺点

  • 易受CSRF攻击:基于cookie的一种跨站伪造攻击。因为基于cookie来识别用户,用户本身携带cookie值,一旦cookie被截获,用户就容易被伪造身份进行非法操作。
  • 跨域问题:Cookie的发送由浏览器自动管理,浏览器和服务器规定了一系列对Cookie发送的限制,使得Cookie在跨域使用时非常麻烦。例如SameSite属性默认限制跨站点发送;Domain和Path绑定到特定域名和路径;Secure和HttpOnly受协议和客户端行为影响。

使用场景:适用于同域下的Web应用,对安全性要求不是极高,且不需要频繁进行跨域操作的场景。

Token验证

Token是用户身份的一种验证方式,通常被称为“令牌”。当用户首次登录后,服务器生成一个Token并返回给客户端,此后客户端每次请求数据时,只需带上这个Token,无需再次携带用户名和密码。

最简单的Token组成包含:

  • uid:用户唯一的身份标识。
  • time:当前时间的时间戳,可用于验证Token的时效性。
  • sign:签名,由Token的前几位 + 盐以哈希算法压缩成一定长度的十六进制字符串,用于防止恶意第三方拼接Token请求服务器。

也可以把一些不变的参数放进Token,减少查库次数。

验证流程如下

  1. 客户端使用用户名跟密码请求登录。
  2. 服务端收到请求,验证用户名与密码。
  3. 验证成功后,服务端签发一个Token,并发送给客户端。
  4. 客户端收到Token后,可将其存储起来,比如放在Cookie里或者Local Storage里。
  5. 客户端每次向服务端请求资源时,需带上服务端签发的Token。
  6. 服务端收到请求后,验证客户端请求中携带的Token。若验证成功,返回客户端请求的数据。

优点

  • 无状态:服务端无需保留用户的认证信息或者会话信息,基于Token认证机制的应用无需考虑用户在哪一台服务器登录,解决了Session扩展性的弊端。
  • 时效性:相比session - cookie中固定不变的sessionid,Token可以在一段时间内动态改变,安全性更高。
  • 可扩展性:服务端不保存Token信息,在分布式系统中,各个节点只需验证Token的真实性,具有更好的扩展性。

缺点

  • 占带宽:正常情况下Token比session_id更大,需要消耗更多流量,挤占更多带宽,不过在实际应用中,这种影响通常可忽略不计。
  • 性能问题:相比于session - cookie,服务端验证Token需要花费更多时间和性能进行解密验证,可看作是一种“时间换空间”的方案。

使用场景:广泛应用于前后端分离架构、分布式系统以及对安全性和扩展性要求较高的应用中。例如,许多移动应用的后端服务采用Token鉴权,方便客户端在不同设备、不同网络环境下进行访问。

JWT(JSON Web Tokens)

JWT是一种特殊的Token,属于一种开放标准(RFC 7519),用于在网络应用中安全地传输信息。当服务器认证用户后,会生成一个JSON对象并发送给用户。之后,用户与服务器通信时,服务器完全依靠这个对象来认定用户身份。为防止用户篡改数据,服务器生成该对象时会加上签名。

JWT的数据结构
JWT是一个很长的字符串,中间用点(.)分隔成三个部分,分别是Header(头部)、Payload(负载)、Signature(签名)。

  • Header:是一个JSON对象,描述JWT的元数据。例如:
  • {
         
     "alg": "HS256",
     "typ": "JWT"
    }
    

其中,alg属性表示签名的算法,默认是HMAC SHA256(写成HS256);typ属性表示这个令牌(token)的类型(type),JWT令牌统一写为JWT。头部的JSON对象会使用Base64URL算法转成字符串。

  • Payload:也是一个JSON对象,用于存放实际需要传递的数据。同样,这个JSON对象也要使用Base64URL算法转成字符串。需要注意的是,JWT默认不加密,任何人都能读取,所以不要把敏感信息放在这个部分。
  • Signature:是对前两部分的签名,用于防止数据篡改。签名的生成需要指定一个密钥(secret),然后使用Header里面指定的签名算法(默认是HMAC SHA256)。例如:
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)

优点

  • 无状态:服务器无需保存任何session数据,变成无状态的,更容易实现扩展,在分布式系统中优势明显。
  • 跨语言支持:由于JWT是基于JSON格式的,几乎所有的编程语言都能很好地支持和处理JSON,方便在不同语言开发的前后端之间传递和验证。

缺点

  • 不可控性:JWT一旦签发,就不再受服务端控制,因为它在服务端没有记录。这既是它最大的优点,也是最大的缺点,可能会导致一定的不可控性。例如,若JWT泄露,在其过期之前,恶意用户都可以使用它访问受保护资源。

使用场景:常用于前后端分离的Web应用、单页应用(SPA)以及移动应用的身份验证和授权场景,尤其是在分布式系统和微服务架构中,因其无状态和易于扩展的特性而备受青睐。

单点登录(SSO - Single Sign - On)

单点登录允许用户只需登录一次,即可访问所有相互信任的应用系统。通常,SSO需要一个独立的认证中心(passport),子系统的登录均通过passport完成,子系统本身不参与登录操作。当一个系统成功登录后,passport会颁发一个令牌给各个子系统,子系统可凭借该令牌获取各自的受保护资源。为减少频繁认证,各个子系统在被passport授权后,会建立一个局部会话,在一定时间内无需再次向passport发起认证。

实现流程示例

  1. 用户访问子系统A,A系统检测到用户未登录,重定向用户到认证中心(passport)。
  2. 用户在认证中心输入用户名和密码进行登录。
  3. 认证中心验证用户信息成功后,生成一个SSO - Token(或Ticket),并将其返回给子系统A,同时为用户在认证中心建立全局会话。
  4. 子系统A收到SSO - Token后,存储该Token,并建立局部会话,同时将用户重定向回原本请求的页面。
  5. 当用户访问另一个子系统B时,B系统检测到用户未登录,同样重定向用户到认证中心。
  6. 认证中心检测到用户已登录,且持有有效的SSO - Token,直接将该Token发送给子系统B。
  7. 子系统B收到Token后,验证其有效性,若有效,则建立局部会话,允许用户访问。

优点

  • 提升用户体验:用户无需在多个应用系统中重复登录,大大提高了使用效率和便捷性。
  • 集中管理:认证中心统一管理用户的登录信息,便于进行用户身份验证和权限管理,降低了管理成本。

缺点

  • 复杂度增加:需要搭建和维护独立的认证中心,涉及多个系统之间的协作和交互,系统架构变得更加复杂。
  • 安全风险:一旦认证中心出现安全问题,如被攻击导致用户信息泄露,将会影响到所有依赖该认证中心的子系统。

使用场景:适用于企业内部多个相互关联的应用系统之间,或者大型互联网平台下的多个子业务系统之间,实现统一的用户登录和权限管理,提升用户体验和管理效率。例如,大型企业的办公系统,员工通过一次登录即可访问邮件系统、OA系统、文件管理系统等多个内部应用。

OAuth(开放授权)

OAuth是目前最流行的授权机制,主要用于授权第三方应用获取用户数据。简单来说,OAuth就是一种授权机制,数据的所有者告知系统,同意授权第三方应用进入系统获取相关数据,系统会生成一个短期的进入令牌(token),第三方应用使用该令牌代替密码进行访问。

令牌与密码的差异

  • 有效期:令牌是短期的,到期会自动失效,用户无法自行修改;而密码一般长期有效,除非用户主动修改。
  • 可撤销性:令牌可以被数据所有者随时撤销,撤销后立即失效;密码一般不允许被他人撤销。
  • 权限范围:令牌有权限范围(scope),例如只能访问特定的资源或执行特定的操作;而密码通常具有完全的访问权限。

OAuth 2.0的授权流程(以常见的授权码模式为例)

  1. 第三方应用(客户端)向资源所有者(用户)请求授权,并提供一个回调URL。
  2. 资源所有者同意授权后,用户代理(通常是浏览器)将用户重定向到认证服务器。
  3. 认证服务器验证用户身份后,向用户展示授权页面,询问用户是否同意第三方应用获取其资源。
  4. 用户同意授权后,认证服务器生成一个授权码,并将用户重定向回第三方应用提供的回调URL,同时将授权码作为参数传递给第三方应用。
  5. 第三方应用收到授权码后,使用该授权码向认证服务器请求访问令牌。在请求过程中,第三方应用需要提供自己的客户端ID和客户端密钥进行身份验证。
  6. 认证服务器验证授权码和第三方应用的身份后,生成访问令牌(access token)和刷新令牌(refresh token),并将它们返回给第三方应用。
  7. 第三方应用使用访问令牌访问资源服务器上的受保护资源。访问令牌的有效期通常较短,当访问令牌过期后,第三方应用可以使用刷新令牌向认证服务器请求新的访问令牌。

优点

  • 安全:通过令牌代替密码,减少了密码泄露的风险。同时,令牌具有有效期和权限范围限制,进一步增强了安全性。
  • 方便第三方应用接入:对于第三方应用开发者来说,OAuth 2.0提供了一种标准的授权方式,简化了接入流程,降低了开发成本。

缺点

  • 流程复杂:OAuth 2.0的授权流程涉及多个步骤和多个角色之间的交互,相对较为复杂,理解和实现起来有一定难度。
  • 依赖认证服务器:整个授权过程依赖于认证服务器的可靠性和安全性,如果认证服务器出现故障或被攻击,可能会影响第三方应用的正常使用。

使用场景:广泛应用于需要第三方应用接入的场景,如社交媒体平台允许第三方应用获取用户的部分信息(如头像、昵称等),以实现更丰富的功能。在互联网应用中,常见的“使用微信登录”“使用QQ登录”等功能,背后大多采用了OAuth 2.0授权机制。

应用实例:Vue项目中使用路由守卫实现前端鉴权

在前后端分离的项目中,前端需要对用户的访问进行鉴权,以确保用户只能访问其有权限访问的页面。以Vue项目为例,我们可以使用路由守卫来实现前端鉴权。

什么是路由守卫
路由守卫(Route Guard)是Vue.js中vue - router提供的一种功能,用于在路由切换时执行特定的逻辑,以控制和管理路由的访问。它类似于现实生活中的门卫,负责检查用户是否有权限进入某个区域(在这里指的是路由对应的页面或组件)。路由守卫可以在路由导航的不同阶段被调用,包括全局守卫、路由独享守卫和组件内守卫,通过它们可以实现诸如登录验证、权限控制、页面跳转控制等功能。

实现前端鉴权的步骤

  1. **设置页面

前端开发,鉴权方式,Token,Session,Cookie,JWT,OAuth,OpenID Connect, 单点登录,权限管理,跨域认证,身份验证,API 安全,Bearer Token, 认证流程



资源地址:
https://pan.quark.cn/s/50438c9ee7c0


目录
相关文章
|
11月前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
4月前
|
数据采集 Web App开发 JavaScript
无头浏览器技术:Python爬虫如何精准模拟搜索点击
无头浏览器技术:Python爬虫如何精准模拟搜索点击
|
5月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1180 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
|
关系型数据库 数据库 Ruby
Linux 下安装 Redmine
Redmine 是一款非常流行的项目管理工具,使用 Ruby on Rails 编写,采用 GPL 许可协议(GNU General Public License v2)发布,支持多种操作系统。本文记录在 Ubuntu 16.04 下安装部署 Redmine 3.4.6 的过程,以及在 ECS 环境下的测试验证步骤。
6448 0
|
5月前
|
人工智能 Java API
MCP客户端调用看这一篇就够了(Java版)
本文详细介绍了MCP(Model Context Protocol)客户端的开发方法,包括在没有MCP时的痛点、MCP的作用以及如何通过Spring-AI框架和原生SDK调用MCP服务。文章首先分析了MCP协议的必要性,接着分别讲解了Spring-AI框架和自研SDK的使用方式,涵盖配置LLM接口、工具注入、动态封装工具等步骤,并提供了代码示例。此外,还记录了开发过程中遇到的问题及解决办法,如版本冲突、服务连接超时等。最后,文章探讨了框架与原生SDK的选择,认为框架适合快速构建应用,而原生SDK更适合平台级开发,强调了两者结合使用的价值。
7533 33
MCP客户端调用看这一篇就够了(Java版)
|
7月前
|
机器学习/深度学习 人工智能 编解码
Step-Video-TI2V:开源视频生成核弹!300亿参数+102帧电影运镜
Step-Video-TI2V 是阶跃星辰推出的开源图生视频模型,支持根据文本和图像生成高质量视频,具备动态性调节和多种镜头运动控制功能,适用于动画制作、短视频创作等场景。
385 0
Step-Video-TI2V:开源视频生成核弹!300亿参数+102帧电影运镜
|
开发框架 IDE Java
java制作游戏,如何使用libgdx,入门级别教学
本文是一篇入门级教程,介绍了如何使用libgdx游戏开发框架创建一个简单的游戏项目,包括访问libgdx官网、设置项目、下载项目生成工具,并在IDE中运行生成的项目。
490 1
java制作游戏,如何使用libgdx,入门级别教学
|
12月前
|
Docker 容器
docker:记录如何在x86架构上构造和使用arm架构的镜像
为了实现国产化适配,需将原x86平台上的Docker镜像转换为适用于ARM平台的镜像。本文介绍了如何配置Docker buildx环境,包括检查Docker版本、安装buildx插件、启用实验性功能及构建多平台镜像的具体步骤。通过这些操作,可以在x86平台上成功构建并运行ARM64镜像,实现跨平台的应用部署。
7816 2
|
Ubuntu 安全 程序员
一文带你了解软件版本号
【9月更文挑战第3天】
3075 12
一文带你了解软件版本号