1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        你想知道的 HTTP Cookie 都在這

        共 6944字,需瀏覽 14分鐘

         ·

        2024-04-10 15:00

        1 為什么有 Cookie

        1.1 背景

        客戶端和服務(wù)器通過 HTTP 協(xié)議通信,它是一種無(wú)狀態(tài)的協(xié)議,客戶端每次發(fā)送請(qǐng)求時(shí),首先要和服務(wù)器端建立一個(gè)連接,在請(qǐng)求完成后又會(huì)斷開這個(gè)連接。這種方式可以節(jié)省傳輸時(shí)占用的連接資源,但同時(shí)也存在一個(gè)問題:每次請(qǐng)求都是獨(dú)立的,服務(wù)器端無(wú)法判斷本次請(qǐng)求和上一次請(qǐng)求是否來自同一個(gè)用戶。

        為了解決 HTTP 無(wú)狀態(tài)的問題,Lou Montulli 在 1994 年的時(shí)候,推出了 Cookie。

        1.2 什么是 Cookie

        HTTP Cookie(也叫 Web Cookie 或?yàn)g覽器 Cookie)是服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù),瀏覽器會(huì)存儲(chǔ) Cookie 并在下次發(fā)起請(qǐng)求時(shí)攜帶。如下圖示例:

        89d82d0dc82ac05e99a951d0f99416a5.webp

        注:根據(jù) HTTP 協(xié)議的規(guī)定,每個(gè)域名下的 Cookie 總大小不能超過4KB(4096字節(jié))。如果超過該限制,瀏覽器會(huì)自動(dòng)截?cái)?Cookie 內(nèi)容。

        2 如何種 Cookie

        2.1 后端

        e9c00d82812ac2a89acd1ce9e5dd4ad2.webp


        服務(wù)端示例代碼(node)

              
              const https = require('https');
        const path = require('path');
        const fs = require('fs');

        let cookieNum = 0;

        const server = https.createServer(options, (req, res) => {
          if (req.headers.origin) {
            // 設(shè)置允許跨域的域名
            res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
            // 設(shè)置允許的請(qǐng)求方法
            res.setHeader('Access-Control-Allow-Methods''GET, POST, OPTIONS');
            // 設(shè)置允許的請(qǐng)求頭
            res.setHeader('Access-Control-Allow-Headers''Content-Type');

            res.setHeader('Access-Control-Allow-Credentials'true);
          }

          // 處理預(yù)檢請(qǐng)求(OPTIONS請(qǐng)求)
          if (req.method === 'OPTIONS') {
            res.writeHead(200);
            res.end();
            return;
          }

          // 處理其他請(qǐng)求
          if (req.url === '/login' && req.method === 'GET') {
            // 設(shè)置一個(gè)名為 "my-cookie" 的 Cookie,值為 "abc-*",有效期為 1 小時(shí)
            res.setHeader(
              'Set-Cookie',
              `my-cookie=abc-${cookieNum++}; Max-Age=3600; HttpOnly; Domain=b.com; SameSite=None; Secure;`
            );
            res.end('Cookie has been set!');
          } else if (req.url === '/getList' && req.method === 'GET') {
            res.end();
          } else {
            res.writeHead(404);
            res.end();
          }
        });

        server.listen(3001, () => {
          console.log('Server is running on port 3001');
        });

        可在瀏覽器查看種完的 Cookie,如下:

        7ae75571d860e47aa22ffaf22d4e318f.webp

        注:只能種跟接口域名同站的 Cookie,比如 test.b.com/login 接口不能種 Domain=c.com 下的 Cookie。

        6c49183be55f7907586adadee969b80e.webp

        2.2 Cookie 屬性

        2.2.1 Expires & Max-Age

        兩者都可以設(shè)置 Cookie 有效期,Max-Age 優(yōu)先級(jí)更高。過期后 Cookie 就不會(huì)再跟著請(qǐng)求發(fā)送到服務(wù)器。也會(huì)自動(dòng)刪除 Chrome DevTools -> Application -> Cookies  過期的 Cookie。

        2.2.2 Domain

        控制 Cookie 在哪些域名下可見可訪問,如果指定了一個(gè) Cookie Domain=ele.me,則它與所有的子域名(help.ele.me)共享 Cookie??梢岳斫鉃?Cookie 遵守的是「同站」策略。

        什么是同站:只要兩個(gè) URL 的 eTLD+1 相同即是「同站」,否則就是「跨站」,不需要考慮協(xié)議和端口。定義如下:

        eTLD: (effective top-level domain) 有效頂級(jí)域名,如 .com、.me、.github.io、.top 等

        eTLD+1: 有效頂級(jí)域名 + 二級(jí)域名,如 ele.me,taobao.com

        2.2.3 Path

        控制 Cookie 在哪些路徑下可訪問,默認(rèn)值為 / 也就是所有接口路徑都可訪問

        如:Path=/api/

        https://ele.me/api/getList 會(huì)攜帶 Cookie

        https://ele.me/abc/getList 不攜帶 Cookie

        2.2.4 HttpOnly

        阻止 JavaScript 通過 Document.cookie 屬性讀寫 Cookie。通過document.cookieapi 無(wú)法讀、寫對(duì)應(yīng)的 Cookie

        2.2.5 Secure

        只有 https 協(xié)議(localhost 不受此限制)的請(qǐng)求才會(huì)攜帶 Cookie

        2.2.6 SameSite

        限制跨站請(qǐng)求不發(fā)送 Cookie,這樣可以在一定程度上防范跨站請(qǐng)求偽造攻擊(CSRF)

        Strict(嚴(yán)格): 只發(fā)送同站請(qǐng)求的 Cookie,不會(huì)發(fā)送任何形式的跨站 Cookie

        Lax(寬松): 默認(rèn)值,一般情況下只發(fā)送同站 Cookie,有一些特殊情況可以發(fā)送跨站 Cookie,需要滿足以下條件可以發(fā)送跨站 Cookie:

        1. 必須是 GET 或者 HEAD 請(qǐng)求,不能是 POST 請(qǐng)求
        2. 必須是頂級(jí)導(dǎo)航請(qǐng)求,可以認(rèn)為該請(qǐng)求會(huì)改變?yōu)g覽器地址欄 URL,比如通過 a 標(biāo)簽跳轉(zhuǎn)的請(qǐng)求

        舉例:先在 test.b.com 網(wǎng)站下用 test.b.com/login 接口種 Lax Cookie。然后打開 test.a.com 頁(yè)面,如下圖,該頁(yè)面有個(gè) a 標(biāo)簽,點(diǎn)擊會(huì)跳轉(zhuǎn)到 test.b.com,此時(shí)會(huì)攜帶 Lax Cookie,但不會(huì)攜帶 Strict Cookie

        acc5bb553c8039bae5f94202fcd15e71.webp

        None: 跨站和同站請(qǐng)求均發(fā)送 Cookie。在設(shè)置這個(gè)屬性值時(shí),必須同時(shí)設(shè)置 Secure 屬性,比如:SameSite=None; Secure

        468a3a3837551ee39bccbaa4d6d90a8f.webp

        b3ea0f06c9569ddb9444336a863c30f6.webp

        SameSite=None + Secure 屬性的方式在瀏覽器禁用三方 Cookie 之前可用,如果瀏覽器禁用三方 Cookie 需要怎么設(shè)置呢?-- 需要配合 Partitioned 屬性一起使用

        2.2.7 Partitioned

        在瀏覽器禁用三方 Cookie 之前SameSite=None; Secure方式可正常使用,禁用三方 Cookie 后需要配合 Partitioned 屬性使用。瀏覽器開啟禁用三方 Cookie 時(shí),set cookie 報(bào)錯(cuò),如下:

        38124a769344e3b9fe642e1bfbcc78b3.webp

        當(dāng) Set Cookie 增加 Partitioned 屬性后,Cookie 種成功,如下:

        2e7a4e95650b73eb115f52af9357affb.webp

        對(duì)應(yīng)域的請(qǐng)求也可以正常攜帶 Cookie,如下:

        40a79b0a8e068b5367b96ccd67917b3d.webp

        設(shè)置 Partitioned 屬性之前

        到這里你可能會(huì)疑問,為什么要增加 Partitioned 屬性?不是多此一舉嗎?那我們看下之前有什么問題

        隱私問題

        三方 Cookie 可以跨站跟蹤用戶的行為,因此可能會(huì)泄露用戶的個(gè)人信息和瀏覽習(xí)慣,比如:用戶先訪問淘寶,網(wǎng)站會(huì)通過 gm.mmstat.com/arms.1.1 接口種一個(gè) sca Cookie,然后用戶點(diǎn)擊感興趣的商品也會(huì)有 gm.mmstat.com 埋點(diǎn)請(qǐng)求,同時(shí)會(huì)攜帶 sca Cookie,如下圖:

        5a203ee57bd6d24b88314bfd9a7aebbe.webp

        之后用戶打開天貓,也會(huì)攜帶淘寶網(wǎng)站生成的 sca Cookie,這樣 gm.mmstat.com 對(duì)應(yīng)的服務(wù)就有能力分析出來用戶的行為路徑,用戶的行為習(xí)慣就會(huì)被追蹤

        65413836b72f7ec6c0e0e697ad26bd9f.webp

        安全問題

        三方 Cookie 可能被黑客利用來進(jìn)行惡意攻擊,比如偽造跨站請(qǐng)求攻擊(CSRF),示例如下:

        97cf557bd2fa202c43a4174be3b52fa1.webp

        加 Partitioned 屬性之后

        加 Partitioned 屬性后,Chrome 內(nèi)核(從 114 版本開始)的瀏覽器會(huì)對(duì) Cookie 進(jìn)行分區(qū)。如下圖,站點(diǎn) A 內(nèi)嵌入了站點(diǎn) C,站點(diǎn) C 設(shè)置了一個(gè)帶有 Partitioned 屬性的 Cookie,這個(gè) Cookie 將保存在一個(gè)專門用于站點(diǎn) A 嵌入 C 時(shí)設(shè)置的 Cookie 分區(qū)中。只有 C 是 A 網(wǎng)站的子應(yīng)用時(shí)才會(huì)發(fā)送該 Cookie。

        這時(shí)有個(gè)新站點(diǎn) B,內(nèi)嵌了站點(diǎn)C,這時(shí) C 站點(diǎn)接口不會(huì)攜帶上面在 A 站點(diǎn)設(shè)置的 Cookie

        fc04976ce0260ef1273be397a837e88e.webp

        如果用戶直接訪問 C 網(wǎng)站,C 網(wǎng)站的請(qǐng)求不會(huì)攜帶嵌入在 A 中設(shè)置的分區(qū) Cookie,這樣既能保證當(dāng)前頁(yè)面三方 Cookie 的可用性,也能避免上面提到的隱私問題、安全問題。

        4c61b28f76976582a3854de3ef141b45.webp

        2.3 前端

        前端種 Cookie 代碼如下:

              
              document.cookie = 'my-js-cookie=abc; Max-Age=3600; Path=/; Domain=b.com; SameSite=None; Secure;'

        8c22baeceddf82d1bcc2d96a49e19c9e.webp

        局限性

        • 只能種跟當(dāng)前頁(yè)面域名同站的 Cookie 比如,在 test.a.com 頁(yè)面下,document.cookieapi 只能種 Domain=a.com 下的 Cookie,不能種 Domain=b.com 下的 Cookie。

        • 不能重寫有 HttpOnly 屬性的同名 Cookie 線上故障 Case:某App iOS 端 默認(rèn)向 webview 容器里種 sid Cookie 作為登錄態(tài),并且指定 HttpOnly 屬性,但切換賬號(hào)后容器并沒有更新 sid,H5 使用 document.cookie api 也無(wú)法重寫 sid,導(dǎo)致內(nèi)嵌的 H5 頁(yè)面鑒權(quán)失敗。如果使用后端接口種 Cookie 就沒有這個(gè)問題。

        • 安全問題,跨站請(qǐng)求偽造攻擊(CSRF)

        3 瀏覽器禁用三方 Cookie 計(jì)劃

        3.1 Chrome 禁用三方 Cookie

        從 Chrome 114 版本開始,無(wú)痕模式默認(rèn)開啟禁用三方 Cookie。

        26741d977365dcd594ef78bb12c789ac.webp

        9f0430208d6bcdbdfe864a743de14b0b.webp

        下面是 Chrome 禁用三方 Cookie 的計(jì)劃

        80a140785c8d33068e802470bd44bd9d.webp

        3.2 Safari 禁用三方 Cookie

        目前(2023.11.8) Safari 瀏覽器默認(rèn)禁用三方 Cookie,也不支持 Partitioned 屬性,需要手動(dòng)設(shè)置允許跨站 Cookie 才行,設(shè)置入口如下:

        9a87d662ba28c6003b198a1f33294f86.webp

        3.3 對(duì)現(xiàn)有業(yè)務(wù)影響

        只要使用了三方 Cookie 并且沒有 Partitioned 屬性的業(yè)務(wù)都會(huì)受到影響。

        4 三方 Cookie

        Cookie Domain 與 頁(yè)面 URL eTLD+1 不同

        eTLD+1: 有效頂級(jí)域名 + 二級(jí)域名,如 ele.me,taobao.com,如:test.a.com 頁(yè)面下種了 Domain=b.com Cookie,則是三方 Cookie

        請(qǐng)求接口協(xié)議與頁(yè)面協(xié)議不同也屬于三方 Cookie

        如果頁(yè)面域名和接口域名的 eTLD+1 相同,但頁(yè)面域名是 http 協(xié)議,接口是 https 協(xié)議,也屬于三方 Cookie

        iframe 嵌入的三方子應(yīng)用

        如果嵌入的 iframe 子應(yīng)用域名與宿主應(yīng)用域名不是同站,則它是第三方內(nèi)容,三方網(wǎng)站內(nèi)使用的 Cookie 都屬于三方 Cookie。

        如下圖,宿主頁(yè)面(test.a.com)通過 iframe 嵌入子頁(yè)面(test.b.com),子頁(yè)面無(wú)法設(shè)置 Domain=b.com 域下的未分區(qū)的 Cookie。

        • a7b60123612aba2b1b21440672c6357d.webp

        5 參考

        • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview#http_%E6%98%AF%E6%97%A0%E7%8A%B6%E6%80%81%EF%BC%8C%E6%9C%89%E4%BC%9A%E8%AF%9D%E7%9A%84
        • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
        • https://juejin.cn/post/6926731819903631368?searchId=20231106120717EBA1AB4DB9821BC59D77
        • https://developer.chrome.com/docs/privacy-sandbox/chips/
        • https://developer.chrome.com/blog/cookie-countdown-2023oct/
        • https://developer.chrome.com/docs/privacy-sandbox/third-party-cookie-phase-out/
        • https://web.dev/articles/samesite-cookie-recipes?hl=zh-cn#use_cases_for_cross_site_or_third_party_cookies
        瀏覽 30
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            特级**毛片 | 孕妇孕交一区二区三区 | 免费操亚洲熟女 | Jzzijzzij亚洲成熟少妇 | 超碰在线a | 亚洲ⅴ国产v天堂a无码二区 | 色天堂官网 | 主人隔着内裤揉我下面h | www.五月婷婷 | 日本19禁综艺直接啪啪 |