面试官:说说对cookie的理解

375 阅读13分钟

由于经验不足,回答的七零八落,后来总结一下cookie的知识点,如下所示:

cookie背景

Cookie(“cookie”指的是“小甜饼”,也可以称为“HTTP cookie”、“web cookie”、“browser cookie”)最初是由 Netscape 公司在 1994 年引入的一项技术。在 Web 开发早期,Cookie 的主要作用是在客户端存储一些简单的数据,以便跨请求保持状态。例如,当用户登录后,可以在客户端设置一个登录状态的 Cookie,从而实现跨请求保持用户的登录状态,使得用户在不同的页面之间不需要重新登录。

随着 Web 技术的不断发展,Cookie 的作用越来越广泛,除了用于跨请求保持状态之外,还可以用于实现一些高级功能,例如个性化推荐、广告投放、网站访问统计、防止跨站点请求伪造(CSRF)等。

在现代 Web 开发中,Cookie 已经成为了一项非常重要的技术之一,几乎所有的网站都会使用 Cookie 来跨请求保持状态和实现一些高级功能。当然,随着 Web 技术的不断发展,Cookie 也面临着一些挑战,例如隐私保护、安全性等问题,需要不断地进行改进和完善。

为什么需要用到cookie

Web 开发需要使用 Cookie 存储数据的主要原因是要在客户端存储数据,从而跨请求保持状态。由于 HTTP 协议是一种无状态的协议,服务器无法直接记录客户端的状态信息,每次客户端发送请求时,服务器都是无法判断这个请求是来自哪个客户端的,因此无法跨请求保持状态。

在这种情况下,如果要实现跨请求保持状态,就需要在客户端存储一些数据,从而记录客户端的状态信息,而 Cookie 就是其中一种非常方便和灵活的存储方式。通过在客户端设置一个 Cookie,可以将一些简单的数据存储在客户端,并在后续的请求中将这些数据发送给服务器,从而实现跨请求保持状态。

例如,在用户登录后,服务器可以在客户端设置一个登录状态的 Cookie,并在后续的请求中读取这个 Cookie,判断用户是否已经登录。在用户添加商品到购物车后,服务器可以在客户端设置一个购物车信息的 Cookie,并在后续的请求中读取这个 Cookie,从而实现购物车功能。

总之,Web 开发需要使用 Cookie 存储数据,是为了在客户端存储数据,从而跨请求保持状态。Cookie 是一种非常方便和灵活的存储方式,可以在客户端存储一些简单的数据,例如登录状态、购物车信息、用户偏好设置等,从而实现一些常见的功能。

cookie用途

Cookie 是 Web 开发中常用的技术之一,其主要作用是在客户端存储数据,从而跨请求保持状态。下面是一些需要使用 Cookie 的情况:

  1. 用户登录状态:在用户登录后,需要跨请求保持用户的登录状态,从而实现页面之间的交互。这通常通过在客户端设置一个登录状态的 Cookie 来实现。
  2. 购物车信息:在用户添加商品到购物车后,需要跨请求保持商品信息,从而实现购物车功能。这通常通过在客户端设置一个购物车信息的 Cookie 来实现。
  3. 用户偏好设置:在用户更改偏好设置后,需要跨请求保持用户的偏好设置,从而实现个性化功能。这通常通过在客户端设置一个偏好设置的 Cookie 来实现。
  4. 网站访问统计:在统计网站访问量和用户行为时,需要在客户端设置一个统计信息的 Cookie,从而记录用户的行为和偏好,进行数据分析和处理。
  5. 防止重复提交:在表单提交等操作中,需要防止用户重复提交,可以通过在客户端设置一个随机数的 Cookie,从而避免重复提交。

总之,Cookie 是一种非常方便和灵活的技术,可以在客户端存储数据,从而实现跨请求保持状态。在 Web 开发中,常常需要使用 Cookie 来实现一些常见的功能,如用户登录状态、购物车信息、用户偏好设置、网站访问统计等。

如何存储登录态、用户态等标识信息呢?

常见存储方式有:

1.挂在全局变量,缺点是页面一刷新数据就没了

2.存在cookie,storage,只要浏览器没关掉,数据没有手动清除或者过了过期时间就会一直保存这些信息的

相比较于storage,cookie的优点是:借助http头,浏览器能力,可以做到前端无感知。

过程是:

  • 在提供标记的接口,通过 HTTP 返回头的 Set-Cookie 字段,直接「种」到浏览器上
  • 浏览器发起请求时,会自动把 cookie 通过 HTTP 请求头的 Cookie 字段,带给接口

前端无感知:接口请求不用手动去带

什么是 Cookie?

Cookie 是由服务器发送到用户浏览器的小文本文件,用于存储用户的一些数据,例如用户 ID、购物车中的商品、登录状态等。

什么是跨域 Cookie?

跨域 Cookie 是指在不同的域名下共享 Cookie 的方式。由于浏览器的同源策略限制,普通的 Cookie 不能在不同的域名下共享。可以通过以下方法实现跨域 Cookie:

  • 服务器设置 Access-Control-Allow-Credentials 头部,允许客户端发送 Cookie。
  • 在客户端发送请求时,设置 withCredentials 为 true,表示允许发送 Cookie。

Cookie 属性

  • 名称:Cookie 的名称。
  • 值:Cookie 存储的值。
  • 过期时间:Cookie 的过期时间,可以是一个日期或一个时间戳。
  • 域名Domain:Cookie 所属的域名。
  • 路径Path:Cookie 所属的路径。
  • 安全标志:指示浏览器是否只在安全连接上发送 Cookie。
  • SameSite

Domain

限制附带cookie的域名范围是:domain/path

Domain属性指定浏览器发出 HTTP 请求时,哪些域名要附带这个 Cookie。如果没有指定该属性,浏览器会默认将其设为当前 URL 的一级域名,比如 www.example.com 会设为 example.com,而且以后如果访问example.com的任何子域名,HTTP 请求也会带上这个 Cookie。如果服务器在Set-Cookie字段指定的域名,不属于当前域名,浏览器会拒绝这个 Cookie。

Path

Path属性指定浏览器发出 HTTP 请求时,哪些路径要附带这个 Cookie。只要浏览器发现,Path属性是 HTTP 请求路径的开头一部分,就会在头信息里面带上这个 Cookie。比如,PATH属性是/,那么请求/docs路径也会包含该 Cookie。当然,前提是域名必须一致。

Expires / Max-Age

时间范围

Expires属性指定一个具体的到期时间,到了指定时间以后,浏览器就不再保留这个 Cookie。它的值是 UTC 格式。如果不设置该属性,或者设为null,Cookie 只在当前会话(session)有效,浏览器窗口一旦关闭,当前 Session 结束,该 Cookie 就会被删除。另外,浏览器根据本地时间,决定 Cookie 是否过期,由于本地时间是不精确的,所以没有办法保证 Cookie 一定会在服务器指定的时间过期。

Max-Age属性指定从现在开始 Cookie 存在的秒数,比如60 * 60 * 24 * 365(即一年)。过了这个时间以后,浏览器就不再保留这个 Cookie。

当设置了 HTTP Cookie 的 max-age 和 expires 属性时,浏览器会使用以下规则来确定 Cookie 的有效期:

  1. max-age 属性优先级高于 expires 属性。如果 max-age 和 expires 同时存在,浏览器将使用 max-age 属性指定的 Cookie 有效期。
  2. 如果只设置了 expires 属性,那么浏览器将使用 expires 属性指定的 Cookie 有效期。
  3. 如果 max-age 和 expires 属性都未设置,则默认情况下,Cookie 将在会话结束时过期,也就是在用户关闭浏览器时过期。

需要注意的是,即使设置了 Cookie 的有效期,浏览器仍然可以在任何时间删除 Cookie。这可能发生在用户清除浏览器缓存、使用隐身模式浏览网页或者使用浏览器提供的工具删除 Cookie 时。

因此,应该在设计 Web 应用程序时,不依赖于 Cookie 的存在,并尽可能减少对 Cookie 的依赖。如果必须使用 Cookie,请确保 Cookie 只包含必要的信息,不包含敏感数据,并使用 HTTPS 协议来保护 Cookie 的传输。同时,最好设置适当的 Cookie 过期时间,以避免过期 Cookie 对应用程序的影响。

Secure

Secure属性指定浏览器只有在加密协议 HTTPS 下,才能将这个 Cookie 发送到服务器。另一方面,如果当前协议是 HTTP,浏览器会自动忽略服务器发来的Secure属性。该属性只是一个开关,不需要指定值。如果通信是 HTTPS 协议,该开关自动打开。

HttpOnly

HttpOnly属性指定该 Cookie 无法通过 JavaScript 脚本拿到,主要是Document.cookie属性、XMLHttpRequest对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。

SameSite

SameSite 属性是用于设置 Cookie 的属性之一,它用于指示浏览器是否允许跨站点请求发送 Cookie。

在早期的网络环境中,Cookie 经常被滥用,攻击者可以使用跨站点请求伪造 (Cross-Site Request Forgery, CSRF) 的技术来利用用户的 Cookie。为了防止这种攻击,SameSite 属性被引入了。

SameSite 属性有三个可能的值:

  • None:允许跨站点请求发送 Cookie。

  • Strict:禁止跨站点请求发送 Cookie。

  • Lax:限制跨站点请求发送 Cookie,只允许顶级导航(例如点击链接)时发送 Cookie。

    • 当用户从外部站点导航到应用程序的页面时,例如通过点击外部站点上的链接或在地址栏中输入 URL,或者是从其他来源发送 GET 请求(但排除 POST 请求)。
    • 当应用程序使用 GET 方法向同源站点发送请求时。
    • 换句话说,Lax 策略允许在某些情况下发送 Cookie,但在跨站 POST 请求和使用其他方法(例如 XMLHttpRequest)发送请求时禁止发送 Cookie。
    • 使用 Lax 策略可以增加 Cookie 的安全性,因为它可以防止某些跨站请求伪造 (Cross-Site Request Forgery, CSRF) 攻击。但是需要注意的是,Lax 策略仍然存在一定的风险,因为攻击者可以尝试在应用程序的页面上放置恶意代码,例如通过 iframe 或者图片标签来发送 GET 请求。因此,为了提高安全性,建议在应用程序中结合其他安全措施来使用 Lax 策略,例如 CSRF Token、Content Security Policy 等。

默认情况下,如果未设置 SameSite 属性,浏览器会将其设置为 Lax

在设置 SameSite 属性时,需要注意以下几点:

  • 仅支持 HTTPS:如果使用 HTTP 协议发送 Cookie,SameSite 属性将被忽略。
  • 不受所有浏览器支持:虽然 SameSite 属性在现代浏览器中被广泛支持,但仍有一些较老的浏览器不支持它。
  • 不是万无一失的:虽然 SameSite 属性可以提高 Cookie 的安全性,但仍然存在某些攻击可以利用它。

总的来说,使用 SameSite 属性可以帮助减少跨站点请求伪造攻击的风险,但是它并不是一个完美的解决方案,需要与其他安全措施一起使用,例如 HTTPS 协议、CSRF Token 等。

HTTP 是如何写入和传递 cookie 及其配置的呢?

HTTP 返回的一个 Set-Cookie 头用于向浏览器写入「一条(且只能是一条)」cookie,格式为 cookie 键值 + 配置键值。

Set-Cookie: username=feishu; domain=feishu.cn; path=/blog; Expires=Wed, 11 Oct 2022 11:28:00 GMT; Secure; HttpOnly

设置多个cookie,多做几次 Set-Cookie

HTTP 请求的 Cookie 头用于浏览器把符合当前「空间、时间、使用方式」配置的所有 cookie 一并发给服务端。因为由浏览器做了筛选判断,就不需要归还配置内容了,只要发送键值就可以。

Cookie: username=feishu; height=180; weight=80

JS如何获取设置删除cookie

前端可以自己创建 cookie,如果服务端创建的 cookie 没加HttpOnly,也可以修改服务端给的 cookie。

调用document.cookie可以创建、修改 cookie,和 HTTP 一样,一次document.cookie能且只能操作一个 cookie。

设置:调用**document.cookie**设置 cookie

document.cookie = 'username=feishu; domain=feishu.cn; path=/home; Expires=Wed, 11 Oct 2022 10:28:00 GMT; Secure; HttpOnly';

获取: 调用document.cookie也可以读到 cookie,也和 HTTP 一样,能读到所有的非HttpOnly cookie。

let username = document.cookie.split('; ')
    .find(cookie => cookie.startsWith('username=')).split('=')[1];

删除: 把这个 Cookie 的过期时间设置在过去,过期了自然而然就失效了。

document.cookie = 'username=feishu;expires=Thu, 01 Jan 1970 00:00:01 GMT;';

Cookie 的优缺点

它是一种常见的 Web 技术,它的优缺点如下:

优点:

  1. 跨请求保持状态:由于 HTTP 协议是无状态的,Cookie 可以通过在客户端存储数据来跨请求保持状态,从而实现更为复杂的交互操作。
  2. 简单易用:Cookie 的使用非常简单,只需要通过设置 name-value 对和一些其他属性就可以完成。
  3. 支持过期时间:Cookie 可以通过设置过期时间来自动删除,从而可以控制 Cookie 的有效期。
  4. 支持域名限制:Cookie 可以通过设置域名限制来控制 Cookie 的使用范围,从而保障用户的安全性。

缺点:

  1. 存储量有限:每个域名下的 Cookie 数量和存储量都有限制,如果存储过多的 Cookie 数据,会影响页面加载速度和用户体验。
  2. 安全性风险:由于 Cookie 的数据存储在客户端,容易受到攻击者的窃听和篡改,从而导致安全风险。特别是在未设置 HttpOnly、Secure、SameSite 属性时,更容易受到跨站脚本攻击(XSS)和跨站请求伪造(CSRF)等攻击。
  3. 隐私泄露:Cookie 可以用来追踪用户的行为和偏好,如果滥用 Cookie,可能会泄露用户的隐私信息。
  4. 不支持跨域:由于 Same Origin Policy 的限制,Cookie 不能跨域名、跨协议或跨端口使用,这限制了 Cookie 的应用范围和灵活性。

Cookie 和 Session 的区别是什么?

Cookie 和 Session 都可以用于存储用户的信息,但是它们有以下区别:

  • 存储位置不同:Cookie 存储在用户的浏览器中,而 Session 存储在服务器中。
  • 存储内容不同:Cookie 存储的是用户的一些数据,例如用户名、购物车信息等,而 Session 存储的是用户的会话状态,例如登录状态、权限等。
  • 安全性不同:Cookie 存储在用户的浏览器中,可能会被恶意脚本获取,从而泄露用户的信息,而 Session 存储在服务器中,安全性更高。