Web 身份验证:Cookie 与 Token | 8月更文挑战

本文涉及的产品
.cn 域名,1个 12个月
简介: 应用开发一般都少不了身份验证,而身份验证机制的稳定性对所有应用程序都变得至关重要。具体选择何种方式进行身份验证可以根据项目及团队情况来衡量,在决定之前需要先理解WEB身份验证常见的两种方式:基于 Cookie 的身份验证和基于令牌(Token)的身份验证。

应用开发一般都少不了身份验证,而身份验证机制的稳定性对所有应用程序都变得至关重要。具体选择何种方式进行身份验证可以根据项目及团队情况来衡量,在决定之前需要先理解WEB身份验证常见的两种方式:基于 Cookie 的身份验证和基于令牌(Token)的身份验证。

基于 Cookie 的身份验证

身份验证是将用户凭据交换为唯一身份标识的过程。

在基于 Cookie 的身份验证中,此唯一标识符 (Cookie) 在服务器端创建并发送给浏览器。

当登录 Web 应用程序时,浏览器将从其应用程序的服务器接收一个 Cookie,浏览器将存储它并将该 Cookie 与每个后续请求一起发送,以验证请求来自同一用户。

为了更好地理解 Cookie 的工作原理,下面将这个过程分解为 5 个部分。

Cookie 工作流程

1. 使用凭据登录到应用程序

image.png

2. 服务器验证凭据并在创建 session

服务器验证凭证成功后,创建 session ,可以存储在内存或数据库中,为了更好的扩展建议将其存储在数据库中。如果是存储在内存中,在使用负载均衡或多服务器部署的场景下会出现 session  问题。

image.png

3. 服务器通过将cookie包含在Set-Cookie 标头中来响应浏览器

这个 cookie 通过名称值对发送,它包含一个唯一的 id 来标识用户。

image.png

除此之外,Cookie 还可以包含到期日期、作用域和有效时间等详细信息。具有多个 Set-Cookie 标头的示例响应如下所示:

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
[page content]
4. 浏览器将 Cookie 存储在存储中并与后续请求一起发送

当服务器收到带有 Cookie 的请求时,它会将 Cookie 中的 session ID 与数据库中的 session 进行比较以验证用户的有效性。

image.png

可以使用浏览器开发工具在应用程序部分下的 Cookie 存储中找到浏览器中保存的所有 Cookie。

image.png

5. 当用户注销时,服务器将从数据库中删除 session

image.png

一旦用户注销,服务器将通过清除数据库 session 并使 Cookie 过期,浏览器也会从 Cookie 存储中删除它。

Cookie 特征与优缺点

上面简单介绍了一下 Cookie 的工作流程,下面来看看其特征与优缺点。

这是一个完全自动化的过程

如果使用 Cookie 进行身份验证,则无需明确开发任何内容来向请求添加 Cookie

浏览器会负责 Cookie 的处理,它会自动为所有请求添加 Cookie。

尽管这种自动化过程使开发变得更容易,但也有一些缺点。例如,有些请求不需要任何身份验证,但是使用这种方法,Cookie 也将在每个请求中被发送。

此外,CSRF 攻击者可以利用这种机制来欺骗浏览器向虚假网站发送带有 Cookie 的请求。

安全措施

默认情况下,基于 Cookie 的身份验证对攻击没有有效的保护,它们主要容易受到跨站脚本(XSS)和跨站请求伪造(CSRF)攻击。

但是,可以显式地修改 Cookie标头来保护它们免受此类攻击。

例如,在设置 Cookie 头时使用 HttpOnly 属性可以很容易地保护 Cookie 免受 XSS 攻击。

Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

此外,可以在 Cookie 标头中使用 SameSite 属性来有效地防止 CSRF 攻击。

Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax

SameSite 属性有 3 个值可用:

  • SameSite=Lex:将确保浏览器不会在跨站点请求时发送 Cookie(如果没有定义 SameSite 属性,这是 Cookie 的默认行为)。
  • SameSite=Strict : 将确保浏览器仅针对同站点请求发送 Cookie
  • SameSite=Note 将允许通过跨站点和同站点请求发送 Cookie

通常适用于单个域名

除非特别配置,否则 Cookie 仅适用于单个域名。尽管从表面上这似乎是一种限制,但它是默认情况下强制执行单一来源的最强大功能之一。但是,如果前端和后端 (API) 来自不同的域名或子域名,则需要在 Cookie 中将其明确列入白名单。否则,浏览器不会随请求一起发送 Cookie

不适合开放API

如果正在构建一个API来向客户端公开服务,那么 Cookie 可能不是最佳的选择。除非客户端只是浏览器,否则它会使客户端变得复杂。

例如,开发的是一款手机应用,与令牌 Token 相比,拥有 Cookie 将使移动应用程序 Cookie 管理变得复杂。

可能存在可扩展性问题

如前所述,服务器负责 Cookie 设置,需要在数据库中为每个用户存储 session

尽管有成熟的方法来处理可扩展性(例如,使用像 Redis 这样的内存数据库作为 session 的存储),但它仍然增加了更多的复杂性。

但是,随着用户数量的增加,在扩展和管理这些 session 时可能会出现问题。

最适合存储额外的数据

由于这种方法为每个用户维护单独的 session,所以可以存储额外的数据到 session 中。

通过 Cookiesession,可以存储特定的数据,如用户个性化、访问控制和 session。然后,它允许将其用于后续请求。

然而,也可以用 Token 来实现这一点。例如,使用 JWT 令牌,可以存储 Claims 数据。然而,由于它将增加 Token 的大小,保留更多 Token 将影响更高的网络利用率。

可以限制浏览器对 Cookie 的访问

由于 Cookie 提供了 HTTP-Only 选项,可以限制 JavaScript 对它的访问。此外,它将阻止任何访问Cookie与跨站点脚本攻击。

基于令牌Token的认证

引入基于令牌的身份验证是为了解决基于 Cookie 方法的不足。

与Cookie不同,基于Token的方法需要自己实现,Token保存在客户端。

当登录到web应用程序时,服务器将验证凭据并向浏览器发送加密 Token。然后浏览器将存储这个Token,并可以添加到后续请求的授权头中。

然而,基于 Token 方法的标准实现要比上面描述的流程复杂得多。例如,OpenID Connect 引入了多个身份验证流来处理不同类型的用例。

为了更好地理解 Token 的工作方式,下面将这个过程分解为4个部分,并以使用最广泛的 Token 标准 JWT 作为实例。

JSON Web Token (JWT) 是基于令牌的身份验证中最常用的开放标准。

Token的认证工作流程

1. 使用凭据登录到应用程序

image.png

2. 服务器验证凭据,生成令牌并使用密钥对其进行签名,然后将其发送回浏览器

image.png

通常,需要在传输时使用加密(如 SSL)来保护通道。

在服务器端,可以使用像 jsonwebtoken 这样的 NPM 库来生成这些令牌。

npm install jsonwebtoken
const jwt = require("jsonwebtoken");
const privateKey =
    "eyJkYXRhIjp7InVzZXJuYW1lIjoiZGV2cG9pbnQifSwiaWF0IjoxNjI3Njk3ODQ2fQ";
const token = jwt.sign(
    {
        data: {
            username: "devpoint",
        },
    },
    privateKey,
    { algorithm: "HS256" },
    { expiresIn: Math.floor(Date.now() / 1000) + 60 * 60 }
);

使用 jsonwebtoken 生成的 Token 如下所示:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZGV2cG9pbnQifSwiaWF0IjoxNjI3Njk3OTA2fQ.9v0S-74SH5UQwTAqgvNL43fAxQqW3_cajoDsum3TZEo
3. 将 Token 存储在浏览器存储中,并使用JavaScript添加到后续请求中

image.png

浏览器可以将此 Token 存储在本地存储、Session storageCookie 中。然后这个 Token 将被添加到必要请求的授权头中,并发送到服务器端进行请求验证。因此,需要使用 JavaScript 来实现向标头添加Token。

Authorization: Bearer <token>

此外,可以使用 jsonwebtoken 库中的 jwt.decode() 函数来解码此 Token 并在应用程序中使用有效负载数据。

4. 当用户注销时,需要手动从其存储中删除Token

一旦用户退出系统,需要手动清除存储在存储中的 Token,使其无法用于进一步的请求。

Token的认证特征及优缺点

一种无状态机制

Cookie 不同,基于令牌的方法是无状态的。这意味着它不会在数据库或服务器中保存有关用户的任何信息。

服务器只负责创建、验证令牌,这允许构建比基于 Cookie 的方法更具可扩展性的解决方案。

安全问题

尽管令牌试图解决 Cookie 中的安全问题,但它也并不完全安全。

如果应用程序允许将外部 JavaScript 嵌入到应用程序中,则保存在浏览器中的令牌可能容易受到 XSS 攻击。

此外,由于令牌是无状态的,如果暴露在外面,在它到期之前没有办法撤销它。因此,尽可能少地保留令牌至关重要。大部分身份验证服务将 JWT 令牌的有效期设置在 5 分钟以内。

总结

基于令牌和基于 Cookie 的方法是 Web 应用程序最常用的两种身份验证机制。在本文中,讨论了它们的工作原理、特性、优缺点。

正如所看到的,这些方法都不是 100% 完美的,它们各有优缺点。因此,在选择身份验证方法时,建议根据项目要求选择一种,而不是追求完美的方法。


相关文章
|
28天前
|
存储 JSON 安全
如何使用 JSON Web Tokens 进行身份验证?
总的来说,JWT 是一种强大而灵活的身份验证方式,通过正确使用和管理,可以为应用提供可靠的身份验证机制,同时提高系统的可扩展性和安全性。在实际应用中,需要根据具体的需求和场景,合理设计和实施 JWT 身份验证方案。
111 63
|
1月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
70 4
|
3月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
67 0
|
4月前
|
存储 JSON 数据安全/隐私保护
"FastAPI身份验证与授权的奥秘:如何用Python打造坚不可摧的Web应用,让你的项目一鸣惊人?"
【8月更文挑战第31天】在现代Web开发中,保证应用安全性至关重要,FastAPI作为高性能Python框架,提供了多种身份验证与授权方式,包括HTTP基础认证、OAuth2及JWT。本文将对比这些机制并附上示例代码,展示如何使用HTTP基础认证、OAuth2协议以及JWT进行用户身份验证,确保只有合法用户才能访问受保护资源。通过具体示例,读者可以了解如何在FastAPI项目中实施这些安全措施。
175 1
|
4月前
|
存储 安全 搜索推荐
【JavaWeb 秘籍】Cookie vs Session:揭秘 Web 会话管理的奥秘与实战指南!
【8月更文挑战第24天】本文以问答形式深入探讨了Web开发中关键的会话管理技术——Cookie与Session。首先解释了两者的基本概念及工作原理,随后对比分析了它们在存储位置、安全性及容量上的差异。接着,通过示例代码详细介绍了如何在JavaWeb环境中实现Cookie与Session的操作,包括创建与读取过程。最后,针对不同应用场景提供了选择使用Cookie或Session的指导建议,并提出了保障二者安全性的措施。阅读本文可帮助开发者更好地理解并应用这两种技术。
81 1
|
4月前
|
JavaScript 安全 前端开发
Node.js身份验证全攻略:策略与实践,打造坚不可摧的Web应用安全防线!
【8月更文挑战第22天】Node.js作为强大的服务器端JavaScript平台,对于构建高效网络应用至关重要。本文探讨其身份验证策略,涵盖从基于token至复杂的OAuth 2.0及JWT。Passport.js作为认证中间件,支持本地账号验证及第三方服务如Google、Facebook登录。同时介绍JWT轻量级验证机制,确保数据安全传输。开发者可根据应用需求选择合适方案,注重安全性以保护用户数据。
88 1
|
4月前
|
存储 安全 搜索推荐
深入探讨Session和Cookie的概念、用途以及如何在Java Web开发中有效地使用它们进行用户状态管理。
在Java Web开发中,Session和Cookie是管理用户状态的核心技术。Session存储于服务器端,通过唯一的Session ID识别用户,确保数据安全与隐私;Cookie则存储于客户端,用于记录用户偏好等信息。两者各有优势:Session适合存储敏感数据,但需合理管理避免资源浪费;Cookie便于持久化存储,但在安全性上需谨慎设置。开发者可通过Servlet API轻松操作二者,实现个性化用户体验与应用性能优化。
72 2
|
4月前
|
存储 JSON JavaScript
震撼!Cookie、Session、Token、JWT 终极对决:揭开 Web 认证的神秘面纱!
【8月更文挑战第13天】Web 开发中,Cookie、Session、Token 和 JWT 常混淆。Cookie 是服务器给客户端的小信息片,如登录状态,每次请求都会返回。Session 则是服务器存储的用户数据,通过 Session ID 追踪。Token 类似通行证,证明客户端身份且可加密。JWT 是结构化的 Token,含头部、载荷及签名,确保数据完整性和安全性。
75 4
|
4月前
|
开发框架 JSON .NET
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
|
4月前
|
C# 开发者 Windows
WPF遇上Office:一场关于Word与Excel自动化操作的技术盛宴,从环境搭建到代码实战,看WPF如何玩转文档处理的那些事儿
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的重要组件,以其强大的图形界面和灵活的数据绑定功能著称。本文通过具体示例代码,介绍如何在 WPF 应用中实现 Word 和 Excel 文档的自动化操作,包括文档的读取、编辑和保存等。首先创建 WPF 项目并设计用户界面,然后在 `MainWindow.xaml.cs` 中编写逻辑代码,利用 `Microsoft.Office.Interop` 命名空间实现 Office 文档的自动化处理。文章还提供了注意事项,帮助开发者避免常见问题。
300 0
下一篇
DataWorks