前端鉴权机制

  在现代 Web 开发中,身份验证会话管理是不可或缺的组成部分。HTTP是无状态的协议,为了在用户与服务器之间维持状态,前端和后端需要协同使用一些机制来标识用户身份并保障数据安全。本文将围绕 Cookie、Session、Token、JWT 四种常见方式进行介绍与对比,并结合实际说明 Cookie 在前端的基本操作方法。

Cookie:前端存储的基础工具

概念

Cookie 是由服务器发送到客户端并保存在浏览器中的一小段文本数据。它通常用于存储用户的会话信息、登录状态、偏好设置等。浏览器在每次请求该服务器时,都会自动携带相应域下的 Cookie,以便服务器识别用户的身份和状态。

属性

  • name/value:键值对形式存储数据,name 是 Cookie 的名称,value 是对应的值。
  • expires/max-age:设置 Cookie 的过期时间。expires 是一个固定的日期时间,当到达该时间时 Cookie 将失效。max-age 是一个相对时间,单位为秒,表示从设置 Cookie 时开始多少秒后 Cookie 失效。
  • path/domain:限制 Cookie 的作用路径和域名,指定该 Cookie 哪些路径和域名下的请求会带上该 Cookie。
  • secure:仅在 HTTPS 连接下传输该 Cookie,增强安全性,避免在不安全的 HTTP 协议下传输。
  • httpOnly:如果设置了 httpOnly 属性,Cookie 将不能通过 JavaScript 访问,避免被 XSS 攻击窃取。
  • sameSite:控制跨站请求中是否携带 Cookie。可设置为 Strict(严格模式,只有同源请求携带 Cookie)、Lax(宽松模式,部分跨站请求携带 Cookie)或 None(没有限制,所有请求携带 Cookie)。有效防范 CSRF 攻击。

操作方法

设置 Cookie

1
2
3
4
5
// 设置一个简单的 Cookie
document.cookie = "username=Tom; expires=Fri, 01 May 2025 12:00:00 UTC; path=/";

// 设置带有属性的 Cookie
document.cookie = "session_id=abc123; expires=Thu, 01 May 2025 12:00:00 UTC; path=/; secure; httpOnly; sameSite=Strict";

读取 Cookie

1
2
3
4
5
6
7
8
9
10
// 读取所有 Cookie
console.log(document.cookie); // 输出格式: "username=Tom; session_id=abc123"

// 获取特定 Cookie(通过正则匹配)
function getCookie(name) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? match[2] : null;
}

console.log(getCookie("username")); // "Tom"

删除 Cookie

1
2
// 通过设置过期时间为过去的日期删除 Cookie
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";

注意:通过 document.cookie 只能操作非 httpOnly 的 Cookie。

Session:服务端管理的会话机制

概念

Session 是一种由服务器管理的会话机制,用于在用户与服务器之间保持会话状态。在用户登录后,服务器为每个用户创建一个 Session,并生成一个唯一的 Session ID,将其发送到客户端。客户端通常将这个 Session ID 存储在 Cookie 中,每次请求时,浏览器会自动将该 ID 发送到服务器,服务器通过该 ID 识别用户身份并恢复用户状态。

优点

  • 数据存储在服务端,安全性较高:由于用户数据存储在服务器端,不容易受到 XSS 等攻击的威胁,安全性相对较强。
  • 支持复杂的数据存储:Session 可以存储更多结构化的信息(如对象、数组等),而不像 Token 那样只能存储简单的字符串。

缺点

  • 服务器资源占用:每个用户会话需要在服务器端占用一定的内存或存储,随着用户数量的增加,服务器负担较重,扩展性较差。
  • 需要配合 Cookie 或 URL 传递 Session ID:如果 Cookie 被禁用,Session ID 需要通过 URL 传递,可能会暴露在 URL 中,存在一定的安全风险。

Token:无状态的身份令牌

概念

Token 是一种用于用户身份验证的字符串凭证,常用于前后端分离架构中。用户登录成功后,服务器会生成一个 Token 并返回给客户端,客户端在后续的请求中将该 Token 作为身份凭证,通过请求头或 URL 参数传回服务器,从而实现鉴权。Token 不依赖服务端存储用户状态,因此称为“无状态”认证机制。

优点

  • 无状态、可扩展:服务器无需记录每个用户的会话数据,天然适合分布式架构和微服务。
  • 跨平台支持:Token 通常使用字符串格式,前端、移动端、小程序等都易于集成。
  • 适合前后端分离:接口无状态化,前端可灵活控制请求。
  • 可加密处理:通过签名或加密机制提升安全性,防止伪造。

缺点

  • 安全性依赖客户端:Token 一般保存在本地存储(如 localStorage),容易受到 XSS 攻击。
  • 无法主动失效:服务端不记录状态,Token 一旦签发,除非设置过期时间,否则中途无法撤销。
  • 续期管理复杂:需要额外设计刷新机制(如 refresh token),以维持长期会话体验。

JWT:结构化的 Token 实现

概念

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间传递声明(claims)。JWT 通常用于身份验证和信息交换,它由三部分组成:

  • Header:声明 Token 类型(通常是 JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
  • Payload:存储需要传递的数据(如用户信息),该部分是明文可解码的。
  • Signature:由 Header 和 Payload 生成的加密签名,用于验证数据的完整性和防篡改。

优点

  • 自包含:JWT 将认证所需的所有信息包含在内,无需在服务端存储会话数据,便于分布式系统使用。
  • 无状态:JWT 不依赖服务端存储,适合大规模分布式系统和微服务架构。
  • 跨域支持:由于其无状态特性,JWT 易于跨域传输,非常适合前后端分离的项目。
  • 可加密和签名:JWT 可以使用密钥签名,防止数据篡改,也可以加密确保数据的机密性。

缺点

  • 明文数据暴露:Payload 部分是明文数据,虽然签名保证数据完整性,但敏感信息仍然暴露在 Token 内,使用时需谨慎。
  • Token 管理复杂:JWT 的无状态特性意味着服务端无法强制失效某个 Token,因此需要额外设计 Token 刷新机制或过期时间。
  • 过期管理:Token 的过期时间通常较短,但刷新机制的实现增加了系统复杂度。

场景

  • 前后端分离项目的用户认证:JWT 可在用户登录后返回给前端,前端每次请求时携带 Token 进行认证。
  • API 接口鉴权:用于保护接口资源,仅授权的用户可访问。
  • 单点登录(SSO):不同系统间共享认证信息,减少用户的多次登录操作。

区别分析

先是一张别,总结一下上面的四点。

特性 Cookie Session Token JWT
存储位置 客户端 服务端 客户端 客户端
安全性 较低(需配置) 较高 中等(加密可提高) 中等(加密可提高)
是否占用服务端资源
是否可跨域 否(需设置)
数据结构 键值对 可存对象 字符串 JSON结构
管理复杂性 简单 中等 中等 略复杂

存储方式

类型 存储位置 控制方
Cookie 浏览器自动保存(document.cookie 服务端可设置(Set-Cookie)或客户端设置
Token(通常是JWT) 本地存储(localStoragesessionStorage)或手动存入Cookie 前端开发者手动控制

发送方式

类型 是否自动携带 携带方式 控制方
Cookie ✅ 自动携带(只要是同源或设置了withCredentials HTTP 请求头中的 Cookie 字段 浏览器自动或开发者设置
Token(JWT) ❌ 手动携带 通常放在 Authorization 头(如 Bearer xxx)或其他自定义头部 开发者手动设置请求头
  • JWT 是一种 Token 的格式,用来做身份验证(比如用户登录后返回的 token)。
  • 通常我们把 JWT 存在 localStoragesessionStorage 中,并在每次请求时 手动带上
  • ❗也可以把 JWT 存在 Cookie 里,这样就可以配合浏览器自动发送,但要小心 CSRF 风险。

传统 Web 登录是 Session + Cookie 组合:

  • 服务端创建 Session,分配一个唯一 ID(session_id),并通过 Set-Cookie 写入浏览器。
  • 浏览器之后的请求会自动携带这个 Cookie,服务端用这个 ID 找回 Session。
作者

Fu9Zhou

发布于

2025-04-12

许可协议