热搜: fiddler git ip 代理
历史搜索

前端开发完整的 HTTP cookie 指南

游客2024-12-20 12:33:01
目录文章目录
  1. Web 开发中的 cookie 是什么?
  2. 后端配置
  3. 谁创建 cookies ?
  4. 如何查看 cookies ?
  5. 我有一个 cookie,现在怎么办?
  6. cookie 可以设置过期时间: Max-Age 和 expires
  7. cookie 的作用域是网站路径: path 属性
  8. cookie 的作用域是域名: domain 属性
  9. Cookies 和公共后缀列表
  10. Cookies 可以通过 AJAX 请求传递
  11. cookie 不能总是通过 AJAX 请求传递
  12. 处理 CORS
  13. Cookie 的 Secure 属性
  14. Cookie 的 HttpOnly 属性
  15. 可怕的 SameSite 属性
  16. Cookies 和 认证
  17. 总结

Web 开发中的 cookie 是什么?

cookie 是后端可以存储在用户浏览器中的小块数据。 Cookie 最常见用例包括用户跟踪,个性化以及身份验证。

Cookies 具有很多隐私问题,多年来一直受到严格的监管。

在本文中,主要侧重于技术方面:学习如何在前端和后端创建,使用 HTTP cookie。

后端配置

后端示例是Flask编写的。如果你想跟着学习,可以创建一个新的 Python 虚拟环境,移动到其中并安装 Flask。

mkdir cookies && cd $_

python3 -m venv venv
source venv/bin/activate

pip install Flask

在项目文件夹中创建一个名为 flask app.py的新文件,并使用本文的示例在本地进行实验。

谁创建 cookies ?

首先,cookies 从何而来? 谁创建 cookies ?

虽然可以使用document.cookie在浏览器中创建 cookie,但大多数情况下,后端的责任是在将响应客户端请求之前在请求中设置 cookie。

后端是指可以通过以下方式创建 Cookie:

  • 后端实际应用程序的代码(Python、JavaScript、PHP、Java)
  • 响应请求的 Web 服务器(Nginx,Apache)

后端可以在 HTTP 请求求中 Set-Cookie 属性来设置 cookie,它是由键/值对以及可选属性组成的相应字符串:

Set-Cookie: myfirstcookie=somecookievalue

什么时候需要创建 cookie? 这取决于需求。

cookie 是简单的字符串。在项目文件夹中创建一个名为flask_app.py的 Python 文件,并输入以下内容:

from flask import Flask, make_response

app = Flask(__name__)

@app.route("/index/", methods=["GET"])
def index():
    response = make_response("Here, take some cookie!")
    response.headers["Set-Cookie"] = "myfirstcookie=somecookievalue"
    return response

然后运行应用程序:

FLASK_ENV=development FLASK_APP=flask_app.py flask run

当该应用程序运行时,用户访问http://127.0.0.1:5000/index/,后端将设置一个具有键/值对的名为Set-Cookie的响应标头。

127.0.0.1:5000是开发中的 Flask 应用程序的默认侦听地址/端口)。

Set-Cookie标头是了解如何创建 cookie 的关键:

response.headers["Set-Cookie"] = "myfirstcookie=somecookievalue"

大多数框架都有自己设置 cookie 的方法,比如 Flask 的set_cookie()

如何查看 cookies ?

访问http://127.0.0.1:5000/index/后,后端将在浏览器中设置 cookie。 要查看此 cookie,可以从浏览器的控制台调用document.cookie

前端开发完整的 HTTP cookie 指南 1

设置了StrictLax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为 None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

下面的设置无效:

Set-Cookie: widget_session=abc123; SameSite=None

下面的设置有效:

Set-Cookie: widget_session=abc123; SameSite=None; Secure

Cookies 和 认证

身份验证是 web 开发中最具挑战性的任务之一。关于这个主题似乎有很多困惑,因为JWT中的基于令牌的身份验证似乎要取代“旧的”、可靠的模式,如基于会话的身份验证。

来看看 cookie 在这里扮演什么角色。

基于会话的身份验证

身份验证是 cookie 最常见的用例之一。

当你访问一个请求身份验证的网站时,后端将通过凭据提交(例如通过表单)在后台发送一个Set-Cookie标头到前端。

型的会话 cookie 如下所示:

Set-Cookie: sessionid=sty1z3kz11mpqxjv648mqwlx4ginpt6c; expires=Tue, 09 Jun 2020 15:46:52 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax

这个Set-Cookie头中,服务器可以包括一个名为sessionsession id或类似的cookie

这是浏览器可以清楚看到的唯一标识符。 每当通过身份验证的用户向后端请求新页面时,浏览器就会发回会话cookie

基于会话的身份验证是有状态的,因为后端必须跟踪每个用户的会话。这些会话的存储可能是:

  • 数据库
  • 像 Redis 这样的键/值存储
  • 文件系统

在这三个会话存储中,Redis 之类应优先于数据库或文件系统。

请注意,基于会话的身份验证与浏览器的会话存储无关。

之所以称为基于会话的会话,是因为用于用户识别的相关数据存在于后端的会话存储中,这与浏览器的会话存储不同。

何时使用基于会话的身份验证

只要能使用就使用它。基于会话的身份验证是一种最简单、安全、直接的网站身份验证形式。默认情况下,它可以在Django等所有流行的 web 框架上使用。

但是,它的状态特性也是它的主要缺点,特别是当网站是由负载均衡器提供服务时。在这种情况下,像粘贴会话,或者在集中的 Redis 存储上存储会话这样的技术会有所帮助。

关于 JWT 的说明

JWT是 JSON Web Tokens的缩写,是一种身份验证机制,近年来越来越流行。

JWT 非常适合单页和移动应用程序,但它带来了一系列新挑战。 想要针对 API 进行身份验证的前端应用程序的典型流程如下:

  • 前端将凭证发送到后端
  • 后端检查凭证并发回令牌
  • 前端在每个后续请求上带上该令牌

这种方法带来的主要问题是:为了使用户保持登录状态,我将该令牌存储在前端的哪个地方?

对于前端开发来说,最自然的事情是将令牌保存在localStorage中。 由于许多原因,这很糟糕。

localStorage很容易从 JS 代码访问,而且它很容易成为XSS攻击的目标。

为了解决此问题,大多数开发人员都将JWT令牌保存在cookie中,以为 HttpOnly 和Secure可以保护 cookie,至少可以免受 XSS 攻击。

将 SameSite 设置为 strict 就可以完全保护 JWT 免受 CSRF 攻击

设置为SameSite = Strict的新SameSite属性还将保护您的“熟化” JWT 免受 CSRF 攻击。 但是,由于SameSite = Strict不会在跨域请求上发送 cookie,因此,这也完全使 JWT 的用例无效。

SameSite=Lax呢? 此模式允许使用安全的 HTTP 方法(即 GET,HEAD,OPTIONS 和 TRACE)将 cookie 发送回去。 POST 请求不会以任何一种方式传输 cookie。

实际上,将JWT标记存储在cookielocalStorage中都不是好主意。

如果你确实要使用 JWT 而不是坚持使用基于会话的身份验证并扩展会话存储,则可能要使用带有刷新令牌的JWT来保持用户登录。

总结

自 1994 年以来,HTTP cookie 一直存在,它们无处不在。

Cookies 是简单的文本字符串,但可以通过DomainPath对其权限进行控制,具有 Secure 的 Cookie,只能通过 HTTP S 进行传输,而可以使用 HttpOnly从 JS 隐藏。

但是,对于所有预期的用途,cookie 都可能使用户暴露于攻击和漏洞之中。

浏览器的供应商和 Internet 工程任务组(Internet Engineering Task Force)年复一年地致力于提高 cookie 的安全性,最近的一步是SameSite

那么,什么才算是比较安全 cookie? ,如下几点:

  • 仅使用 HTTPS
  • 尽可能带有 HttpOnly 属性
  • 正确的 SameSite 配置
  • 不携带敏感数据
标签:cookie