关于cookie:前端应该知道的Cookie知识

前言

最近应用next.js来开发前端网站,在登录环节发现cookie的存储和跨域存在问题,始终没弄懂cookie的原理,看了网上好多大佬的文章,大有播种分享给大家。

Cookie介绍

HTTP cookie(Web cookie,浏览器 cookie)是服务器发送到用户 Web 浏览器的一小段数据。浏览器可能会存储 cookie 并将其与稍后的申请一起发送回同一服务器。通常,HTTP cookie 用于判断两个申请是否来自同一个浏览器——例如,让用户放弃登录状态。它为无状态HTTP 协定 记住有状态信息。

Cookies次要用于三个目标:

1、会话治理:如登录、购物车、游戏分数或服务器应记住的任何其余内容
2、个性化:如用户偏好、主题和其余设置
3、追踪:如记录和剖析用户行为

1、创立 cookie
接管到 HTTP 申请后,服务器能够发送一个或多个Set-Cookie响应头。浏览器通常存储 cookie 并将其与Cookie HTTP 标头内的同一服务器的申请一起发送。您能够指定不应发送 cookie 的过期日期或时间段。您还能够对特定域和门路设置附加限度,以限度 cookie 的发送地位。

Set-Cookie和Header Cookie

HTTP 响应(Response)标头(Header)的Set-Cookie作用:从服务器发送cookie到用户代理。
一个简略的 cookie 设置如下:

Set-Cookie: <cookie-name>=<cookie-value>

这批示服务器发送标头通知客户端存储一对cookie:

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

而后,对于服务器的每个后续申请,浏览器都会应用标头将所有先前存储的 cookie 带回服务器Cookie。

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

2、Cookie 的生命周期

cookie 的生命周期能够通过两种形式定义:

1、以后会话完结时:会删除会话cookie。(浏览器定义“以后会话”何时完结,一些浏览器在重启时应用会话复原。这可能会导致会话 cookie 无限期地继续)
2、永恒cookie:在Expires属性指定的日期或属性指定的一段时间后删除Max-Age。

例如:

Set-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;

留神:
1、当您设置Expires日期和工夫时,它们与设置 cookie 的客户端相干,而不是服务器。
2、要删除Cookie,须要将Max-Age设置为0,并且将Cookie的值设置为null。不要将Max-Age指令值设置为-1正数。否则,浏览器会将其视为会话cookie。
3、如果您的站点对用户进行身份验证,它应该从新生成并从新发送会话cookie,即便是曾经存在的,只有用户进行身份验证。这种办法有助于避免会话固定攻打,第三方能够重用用户的会话。

3、限度对 cookie 的拜访

您能够通过以下两种形式之一确保 cookie 平安发送,并且不会被非预期方或脚本拜访:
1、Secure属性
2、HttpOnly属性。

带有该Secure属性的 cookie 仅通过 HTTPS 协定通过加密申请发送到服务器。它永远不会应用不平安的 HTTP发送(本地主机(localhost)除外),这意味着中间人攻击者无奈轻松拜访它。不平安的站点(http:在 URL 中带有)无奈应用该Secure属性设置 cookie。然而,不要假如这会Secure阻止对 cookie 中敏感信息的所有拜访。例如,有权拜访客户端硬盘(或 JavaScript,如果HttpOnly未设置该属性)的人能够读取和批改信息。

JavaScript API HttpOnly:无法访问具备该属性的 cookie ;
Document.cookie它只发送到服务器。
例如,继续存在于服务器端会话中的 cookie 不须要对 JavaScript 可用,并且应该具备该HttpOnly属性。这种预防措施有助于缓解跨站点脚本 ( XSS ) 攻打。

这是一个例子:

Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly

4、定义 cookie 的发送地位

Domain和Path属性定义了 cookie的范畴:cookie 应该发送到哪些 URL。

4.1 Domain属性

Domain属性指定哪些主机能够接管 cookie。如果未指定,则该属性默认为设置 cookie 的同一主机,不包含 subdomains。
如果指定Domain 则始终蕴含子域。因而,指定Domain比省略它的限度要小。然而,当子域须要共享无关用户的信息时,它会很有帮忙。

例如,如果您设置Domain=mozilla.org,则 cookie 可用于子域,如developer.mozilla.org.

4.2 Path属性

Path属性批示在申请的 URL 中必须存在的 URL 门路,以便发送Cookie标头。( %x2F”/”) 字符被视为目录分隔符,子目录也匹配。
例如,如果您设置Path=/docs,则这些申请门路匹配:

/docs
/docs/
/docs/Web/
/docs/Web/HTTP

然而这些申请门路不会:

/
/docsets
/fr/docs

4.3 SameSite属性

SameSite属性容许服务器指定是否何时通过跨站点申请发送 cookie(其中站点由可注册域和计划定义:http 或 https)。这提供了一些针对跨站点申请伪造攻打 ( CSRF ) 的爱护。它须要三个可能的值:Strict、Lax和None。

应用Strict时,cookie 只会发送到它的起源站点。
Lax相似,除了当用户导航到 cookie 的源站点时发送 cookie。例如,通过跟踪来自内部站点的链接。
None指定在发动申请和跨站点申请时都发送 cookie,但仅在平安上下文中(即,如果还必须设置SameSite=None该属性)。

留神:如果未设置SameSite属性,则 cookie 默认被视为Lax.

例子:

Set-Cookie: mykey=myvalue; SameSite=Strict

问题

介绍完Cookie之后,咱们假如咱们当初有个前后台拆散的我的项目,前端地址是:www.baidu.com,后盾api地址是:api.baidu.com和api.bilibili.com,当初咱们来剖析讲上面几个问题:

1、跨域前后台设置问题
2、跨域Cookie不能携带问题
3、Cookie如何如何防止XSS攻打和CSRF攻打

1、跨域前后台设置问题

如果想让前端拜访后盾两个api地址咱们须要设置如下代码,

前端(以axios为例):

axios.defaults.withCredentials = true

后盾(以spring cloud gateway为例)

spring:
  cloud:
    loadbalancer.ribbon.enabled: false
    gateway:
      globalcors:
        #add-to-simple-url-handler-mapping: true
        cors-configurations:
          '[/**]':
            allowedHeaders: "*"
            allowCredentials: true
            allowedOrigins: 
              - "https://api.baidu.com"
              - "https://api.bilibili.com"
            allowedMethods: "*"
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials

2、跨域Cookie不能携带问题

这里就有意思了,因为咱们前端的地址是www.baidu.com,简称A,后盾api有两个地址:api.baidu.com,简称B和api.bilibili.com,简称C,当咱们通过A申请B的接口的时候,cookie会主动带上,因为他们是属于同源不同域,所以你在A下设置的cookie在申请B时也会带上,而当A申请C时就带不了了,显著两个不同源也不同域,所以无奈带上,如果真要带的话,只有当A申请C时会把C的cookie带给C,而不能把A的cookie带给C,所以当初你晓得该怎么做了吧!

3、Cookie如何防止XSS攻打和CSRF攻打

XSS介绍:
(Cross Site Script )攻打全称为跨站脚本攻打,xss攻打通常指的是利用网页开发留下的破绽,通过奇妙的办法注入歹意的指令代码到网页上,使用户加载并执行歹意制作的网页程序。这些歹意网页程序通常是JavaScript代码

XSS解决:
应用Cookie的HttpOnly属性
严格来说,HttpOnly并非是为了反抗XSS-HttpOnly解决的是XSS后的Cookie劫持攻打。后面说了XSS可能会窃取用户的Cookie,而后就间接登录了该用户的账户,然而如果Cookie设置了HttpOnly,则这种攻打会失败,因为JavaScript读取不到Cookie的值。

CSRF介绍:
CSRF攻打的全称是跨站申请伪造( cross site request forgery),是一种对网站的歹意利用。简略点讲就是,歹意网站(攻击者)盗用了你的身份,以你的名义向信赖网站发送歹意申请。 CRSF能做的事件包含利用你的身份发邮件、发短信、进行交易转账等,甚至盗取你的账号。

CSRF 攻打的三个必要条件:
指标站点肯定要有 CSRF 破绽
用户要登录过指标站点,并且在浏览器上放弃有该站点的登录状态
须要用户关上一个第三方站点,能够是黑客的站点,也能够是一些论坛

CSRF 攻打不会往页面注入歹意脚本,而是找服务器的破绽,因而黑客是无奈通过 CSRF 攻打来获取用户页面数据的,对于 CSRF 攻打,次要的防护伎俩是晋升服务器的安全性。

CSRF解决:
如果是从第三方站点发动的申请,那么须要浏览器禁止发送某些要害 Cookie 数据到服务器;
如果是同一个站点发动的申请,那么就须要保障 Cookie 数据失常发送。
而 Cookie 中的 SameSite 属性正是为了解决这个问题的。

在 HTTP 响应头中,通过 set-cookie 字段设置 Cookie 时,能够带上 SameSite 选项。

总结

1、cookie是所有前端开发人员必须要面对的知识点,大家肯定要把原理弄清楚,这样在理论开发中遇到跨域还是xss、csrf攻打防备的话都可能对症下药

援用

应用 HTTP cookie
浏览器原理 33 # CSRF攻打:为什么Cookie中有SameSite属性?
【信息安全】面试常问CSRF、cookie、session和token
浏览器跨域申请胜利了,然而cookie 没有带过来,求解?

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理