Chrome 扩展程序不会发送 SameSite=Lax cookie



我在通过弹出脚本的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. 在localhost上登录到我的应用程序(所以我得到了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吗?

这是Chromium 77版之前的扩展问题。当跨站点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

我发现cookie的path至关重要。任何不匹配都会导致误导行为。

这是我的设置:

  • localhost:8081上运行的后端服务器
  • chrome清单权限具有"http://localhost:8081/"
  • 后端返回带有path=/的cookie,例如,这是一个示例响应头Set-Cookie: refresh_token=bar; Path=/; SameSite=Lax; HttpOnly
  • chrome扩展可以手动查询cookie:chrome.cookies.get({ url: 'http://localhost:8081/', name: 'refresh_token' }...
  • chrome扩展在您发送到localhost:8081下的其他url路径时自动附加cookie,例如:
    fetch('http://localhost:8081/v1/meh').then((response) => {
    console.log(response);
    })
    
    服务器端将看到refresh_tokencookie

总结一下:在路径/a上设置的cookie不会发送到路径/b上的url;在路径CCD_ 24处设置的cookie将被发送到同一域下的所有url。

内容脚本是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; 
}
});
}())

最新更新