簡體   English   中英

Chrome 擴展程序不發送 SameSite=Lax cookie

[英]Chrome extension doesn't send SameSite=Lax cookies

我在通過彈出腳本中的 chrome 擴展程序處理 cookie 時遇到了一些麻煩。

popup.js 內容:

document.addEventListener('DOMContentLoaded', () => {
    function cookieinfo() {
        chrome.cookies.getAll({url: 'http://localhost:8080'}, function(cookie) {
            console.log('Found cookie: ', cookie)
            if (cookie == null)
                return;

            fetch('http://localhost:8080', {credentials: 'include'}).then((response) => {
                // do some stuff
                return response;
            });
        });
    }
    window.onload=cookieinfo;
}, false);

我執行的步驟:

  1. 在本地主機上登錄我的應用程序(所以我得到了 cookie)
  2. 打開彈窗(所以 popup.js 被執行)
  3. 我在控制台日志中看到 chrome 找到了必要的 cookie
  4. 服務器說傳入請求有空 cookie
  5. 我刷新本地主機應用程序的頁面
  6. 我現在登出

也許有人知道我做錯了什么?

編輯:

原因似乎是我的 cookie 有參數HttpOnly=trueSameSite=Lax相關鏈接)。 我可以在服務器日志中看到另一個 cookie。 但是由於此線程,如果將credentials參數設置為include ,則將發送所有 cookie,甚至是 httpOnly cookie。 由於此答案具有相同的結果,我還嘗試將其發送到 127.0.0.1 而不是 localhost。

我無法將httpOnly設置為 false。 這是由框架強制的。 有人知道怎么修嗎?

編輯2:

我終於安裝了 Cookie 編輯器,發現SameSite=Lax是原因。 如果我將其設置為No Restriction那么我將在服務器端看到它。 不幸的是,我使用的框架只允許LaxStrict選項(Chrome 擴展程序同時失敗)。 有誰知道如何從 Chrome 擴展程序發送 Lax cookie?

這是版本 77 之前 Chromium 中擴展的問題。當跨站點 cookie 設置為SameSite=LaxSameSite=Strict ,cookie 不會與跨站點請求一起發送。

這已在所有平台的 78 版中修復。 現在 Chrome 擴展會在SameSite=LaxSameSite=Strict時發送 cookie。

參考:

https://bugs.chromium.org/p/chromium/issues/detail?id=1007973

https://chromium-review.googlesource.com/c/chromium/src/+/1827503

https://bugs.chromium.org/p/chromium/issues/detail?id=617198

內容腳本是 100% 的解決方案。

您基本上有兩個單獨的瀏覽器,常規瀏覽器和擴展彈出瀏覽器。 但它們是完全獨立的,只能來回發送消息。 所以你需要做的是讓擴展上下文向瀏覽器上下文發送一條消息,指示該上下文中的一些代碼獲取document.cookies並將它們發送回擴展上下文。

這是我從每個單獨的瀏覽器上下文中獲取 cookie 的示例。

清單文件

{
  "manifest_version": 2,
  "name": "Cookie Monster",
  "description": "Nom nom nom nom",
  "version": "1.0",
  "browser_action": {
    "default_popup": "html/extension.html",
    "default_title":"Cookie Monster"
  },
  "permissions": [
    "activeTab",
    "tabs",
    "http://*/*",
    "https://*/*"
 ],
  "content_scripts": [{
    "js":["/js/client.js"],
    "matches":["http://*/*","https://*/*"]
  }]
}

擴展名.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Cookies</title>
    <style>
      body {
        display: block; 
        min-height: 250px; 
        width: 250px; 
        padding: 5px; 
      }
      button {
        display: block; 
        margin: 0 0 10px 0; 
      }
    </style>
  </head>
  <body class="container">
    <h1>Cookies</h1>
    <button id="extension_cookies" type="button">Get PopUp Cookies</button>
    <button id="browser_cookies" type="button">Get Browser Cookies</button>
    <p id="result"></p>

    <script src="/js/extension.js" type="text/javascript"></script>
  </body>
</html>

擴展.js

'use strict';
(function(){
    // cache import DOM elements
    const extension_btn = document.querySelector('#extension_cookies');
    const browser_btn = document.querySelector('#browser_cookies'); 
    const result = document.querySelector('#result');


    // runs in the popup window of the extension, 
    // which is it's own browser context 
    // and has it's own set of cookies
    extension_btn.addEventListener('click', () => {
        if (document.cookie === ''){
            result.innerText = 'No Cookies...';
        } else {
            result.innerText = document.cookie;
        }
    })

    // send message to browser context
    // message will inform browser client of what to do
    // the browser then needs to pass data to the callback function
    // then we can display results
    browser_btn.addEventListener('click', () => {
        chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
            chrome.tabs.sendMessage(tabs[0].id, {message: 'GET_COOKIES'}, (data) => {
                result.innerText = data.cookies
            });
        });
    })
}());

客戶端.js

'use strict';
(function(){

  // receive a callback function so I can pass data to extension
  // get document cookies, put into an object
  // use callback to send response to extension
  const get_browser_cookies = (sendResponse) => {
    const cookies = document.cookie; 
    console.clear(); 
    console.log(cookies);
    sendResponse({ cookies: cookies }); 
  }


  // listen for messages from extension
  // a switch statement can help run only the correct function
  // must pass the function a reference to the sendResponse function
  // so I can pass data back to extension
  chrome.runtime.onMessage.addListener(function(data_from_extension, sender, sendResponse){
    switch (data_from_extension.message){
      case 'GET_COOKIES': {
        get_browser_cookies(sendResponse); 
        break; 
      }
      default: null; 
    }
  });
}())

我發現 cookie 的path至關重要。 任何不匹配都會導致誤導行為。

這是我的設置:

  • localhost:8081運行的后端服務器
  • chrome 清單權限具有"http://localhost:8081/"
  • 后端返回帶有path=/ cookie,例如。 這是一個示例響應頭Set-Cookie: refresh_token=bar; Path=/; SameSite=Lax; HttpOnly Set-Cookie: refresh_token=bar; Path=/; SameSite=Lax; HttpOnly
  • chrome 擴展可以手動查詢cookie: chrome.cookies.get({ url: 'http://localhost:8081/', name: 'refresh_token' }...
  • 當您發送到localhost:8081下的其他 url 路徑時,chrome 擴展程序會自動附加 cookie,例如:
     fetch('http://localhost:8081/v1/meh').then((response) => { console.log(response); })
    服務器端會看到refresh_token cookie。

總結一下:設置在路徑/a的 cookie 不會被發送到路徑/b處的網址; 設置在路徑/的 cookie 將發送到同一域下的所有 url。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM