Расширение Chrome не отправляет SameSite = Lax cookie

У меня проблемы с работой с файлами cookie через расширение Chrome из всплывающего скрипта.

содержимое 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. Я вижу в журнале консоли, что хром обнаружил необходимые файлы cookie
  4. Сервер сообщает, что входящий запрос имеет пустые файлы cookie
  5. Обновляю страницу приложения localhost
  6. Я выхожу из системы сейчас

Может кто знает, что я делаю не так?

Изменить:

Похоже, причина в том, что у моего файла cookie есть параметры HttpOnly=true и SameSite=Lax (соответствующая ссылка). Я вижу другие файлы cookie в журнале сервера. Но из-за этого потока все файлы cookie будут отправлены, если для параметра credentials установлено значение include, даже файлы cookie httpOnly. Также я попытался отправить его на 127.0.0.1 вместо localhost из-за этого ответа с тем же результатом.

Я не могу установить для httpOnly значение false. Это вызвано фреймворком. Кто-нибудь знает как исправить?

Edit2:

Я наконец установил редактор файлов cookie и обнаружил, что причина в SameSite=Lax. Если я установлю No Restriction, я увижу его на стороне сервера. К сожалению, используемый мной фреймворк допускает только параметры Lax и Strict (расширение Chrome не работает с обоими). Кто-нибудь знает, как отправлять файлы cookie Lax из расширения Chrome?


person Defake    schedule 07.08.2018    source источник
comment
Я бы попробовал XMLHttpRequest.   -  person wOxxOm    schedule 07.08.2018
comment
Разве поток ЦП, в котором popup.js не работает, работает отдельно от потока, в котором работает главное окно браузера? Я думаю, вы устанавливаете файлы cookie в экземпляре браузера своего расширения, но вам нужно установить файлы cookie в реальном контексте окна браузера.   -  person TJBlackman    schedule 07.08.2018
comment
@TJBlackman Я попытался сделать это в content.js и background.js с тем же результатом. Или вы имеете в виду другое?   -  person Defake    schedule 07.08.2018
comment
@TJBlackman, похоже, ты прав, потому что document.cookie возвращает пустую строку. Но как мне запустить код в контексте окна браузера, если content_script не является решением?   -  person Defake    schedule 09.08.2018
comment
@wOxxOm без разницы. fetch, XMLHttpRequest и $.ajax работают с одинаковым результатом (не отправляйте этот файл cookie)   -  person Defake    schedule 21.08.2018
comment
Вот связанная ошибка Chromium: bugs.chromium.org/p/chromium / issues / detail? id = 617198   -  person SeinopSys    schedule 05.06.2019


Ответы (3)


Это была проблема с расширениями в Chromium до версии 77. Если для межсайтового файла cookie было установлено значение SameSite=Lax или SameSite=Strict, файл cookie не отправлялся с межсайтовым запросом.

Это было исправлено в версии 78 на всех платформах. Теперь расширение Chrome отправляет файлы cookie, когда SameSite=Lax или SameSite=Strict.

Ссылки:

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

person Ganapati V S    schedule 05.11.2019
comment
Означает ли это, что межсайтовые файлы cookie всегда отправляются из расширений Chrome и что предстоящие изменения SameSite фактически не повлияют на расширения? - person Don't Panic; 07.01.2020
comment
Да, межсайтовые файлы cookie AFAIK всегда отправлялись в более старых версиях расширений Chrome (конечно, только если они не имеют атрибута SameSite). Именно так большинство хром-расширений веб-сайтов работали с файлами cookie веб-сайта без особых изменений. - person Ganapati V S; 07.01.2020

Сценарий содержимого - это 100% решение.

По сути, у вас есть два отдельных браузера: обычный браузер и всплывающий браузер расширения. Но они полностью разделены и могут отправлять сообщения только туда и обратно. Итак, вам нужно сделать так, чтобы контекст расширения отправил сообщение в контекст браузера, которое инструктирует некоторый код в этом контексте получить document.cookies и отправить их обратно в контекст расширения.

Вот пример того, как я получаю файлы cookie из каждого отдельного контекста браузера.

manifest.json

{
  "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://*/*"]
  }]
}

extension.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>

extension.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
            });
        });
    })
}());

client.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; 
    }
  });
}())
person TJBlackman    schedule 09.08.2018
comment
Я пробовал, без разницы. Обновил вопрос, похоже причина в флаге httpOnly. Но я все еще не знаю, как это решить - person Defake; 13.08.2018
comment
Я только что проверил расширение Grammarly chrome. Расширение хорошо работает с их httponly grauth cookie и не запрашивает никакой другой авторизации. Итак, это как-то возможно - person Defake; 20.08.2018
comment
Что ж, вы можете проверить код их расширения и узнать, как они это сделали! chrisle.me / 2012/12 / - person TJBlackman; 21.08.2018
comment
вау, спасибо за трюк. Но это снова была моя ошибка. У моего файла cookie есть параметр SameSite=Lax, а у их - нет. Поэтому я снова обновил вопрос ... - person Defake; 21.08.2018
comment
Кто-нибудь смог найти решение для этого? Я прочитал множество SO-вопросов и пробовал несколько разных вещей, но безуспешно. У кого-нибудь есть решение этого? - person PythonEnthusiast; 30.05.2019
comment
Это своего рода старый вопрос - возможно, вам лучше задать собственный вопрос, относящийся к вашему варианту использования. javascript fetch() api имеет параметр headers: { credentials: 'include'}, который позволяет отправлять файлы cookie только HTTP вместе с запросом на выборку. Могу помочь ... - person TJBlackman; 30.05.2019

Я выяснил, что path файла cookie имеет решающее значение. Любое несоответствие ведет к вводящему в заблуждение поведению.

Это моя установка:

  • внутренний сервер, работающий на localhost:8081
  • разрешение манифеста Chrome имеет "http://localhost:8081/"
  • бэкэнд возвращает cookie с path=/, например. это пример заголовка ответа Set-Cookie: refresh_token=bar; Path=/; SameSite=Lax; HttpOnly
  • Расширение chrome может запрашивать файл cookie вручную: chrome.cookies.get({ url: 'http://localhost:8081/', name: 'refresh_token' }...
  • Расширение chrome автоматически прикрепляет файл cookie, когда вы отправляете его по другим URL-адресам в localhost:8081, например:
    fetch('http://localhost:8081/v1/meh').then((response) => {
        console.log(response);
    })
    
    Серверная сторона увидит refresh_token cookie.

Подводя итог: файл cookie, установленный по пути /a, не будет отправлен по URL-адресу по пути /b; файл cookie, установленный по пути /, будет отправлен на все URL-адреса в одном домене.

person xysun    schedule 20.12.2020