electron [特性]:支持在通过自定义协议加载的页面上使用cookies

vq8itlhq  于 4个月前  发布在  Electron
关注(0)|答案(7)|浏览(166)
  • Electron版本: 12.0.0(实际上,除了beta/夜间测试版之外,我测试了很多其他版本)
  • 操作系统: Linux
  • 最后已知的正常工作的Electron版本:

预期行为

document.cookie: is-paid-user=1 将被打印到控制台。

实际行为

document.cookie: 将被打印到控制台(没有 is-paid-user=1 cookie记录)。

重现方法

在将 web://news.ycombinator.com 更改为 https://news.ycombinator.com 后,问题将消失。

const {app, BrowserWindow, protocol} = require("electron");

const scheme = "web";

protocol.registerSchemesAsPrivileged([{scheme, privileges: {secure: true, standard: true, corsEnabled: true}}]);

app.whenReady().then(() => {
  const window = new BrowserWindow();

  window.webContents.session.protocol.registerBufferProtocol(scheme, (...[, callback]) => {
    callback({mimeType: "text/html", data: Buffer.from("<h5>blank page</h5>")})
  })

  window.loadURL("web://news.ycombinator.com").then(() => {
    window.webContents.openDevTools();
    window.webContents.executeJavaScript(`
document.cookie = "is-paid-user=1;expires=Fri, 31 Dec 2021 20:59:59 GMT;domain=.ycombinator.com;path=/";
console.log("document.cookie: ", document.cookie);
`);
  });
});

截图

  • https协议:

  • web/自定义协议:

其他信息

我的理解是,在 registerSchemesAsPrivileged 调用中设置 standard: true 就足以使 document.cookie 在自定义协议上工作。

fkvaft9z

fkvaft9z1#

是否有解决方案?

6l7fqoea

6l7fqoea2#

在这条线上失败了:https://source.chromium.org/chromium/chromium/src/+/master:net/cookies/cookie_util.cc;l=268;drc=587068ee20325543d40cbd4bf50bed6af51ee23e
因为

cookie_domain_and_registry = ycombinator.com
url_domain_and_registry = news.ycombinator.com

将cookie更改为适用于news.ycombinator.com的结果是,this check被触发了,因为cookieable方案不包括web。不幸的是,看起来要在不影响chrome的情况下影响该列表的唯一方法是通过CookieManagerParams.allow_file_scheme_cookies,这将把file:添加到cookieable方案列表中。没有办法向其中添加任意方案。
简而言之,我们不支持自定义协议上的cookie,如果没有相当大的努力,也无法实现。
...而且看起来我之前在这里做过同样的调查:#20940(评论)
我将其更改为功能请求。如果有人想解决这个问题,我很乐意审查PR,但请注意:我会要求你将任何补丁提交给Chromium。

oxcyiej7

oxcyiej73#

tl;dr 我们不支持自定义协议上的cookies。

这个信息是否在https://www.electronjs.org/docs的某个地方有记录?

6uxekuva

6uxekuva4#

我认为不是这样...我不确定在哪里记录会是最好的地方。你想发起一个文档PR吗?

mlmc2os5

mlmc2os55#

你想发起一个文档PR吗?
还没准备好投入其中。
但是如果文档能更新一下就好了,因为我在提交问题之前已经审阅过了,但接下来的部分误导了我:https://github.com/electron/electron/blame/80f89a34728281cc61cfacd7b682f0227f89a102/docs/api/protocol.md#L101-L104 (注意 cookies 的提及)
默认情况下,对于非标准方案,web存储API(localStorage、sessionStorage、webSQL、indexedDB、cookies)是禁用的。因此,一般来说,如果你想注册一个自定义协议来替换 http 协议,你必须将其注册为标准方案。
我不确定在哪里记录会更好。
所以也许调整会在引用的段落附近落地。

scyqe7ek

scyqe7ek6#

遗憾的是,看起来在不修补Chrome的情况下影响该列表的唯一方法是通过CookieManagerParams.allow_file_scheme_cookies,这将向cookieable scheme列表中添加file:
目前这是可能的吗?
我遇到了一个依赖于cookies工作的第三方SDK的问题。由于我在使用本地开发服务器,它在开发环境中运行得很好,但我还没有通过file:或自定义协议将其打包到生产状态中运行成功。
我看到的另一个选择是运行本地服务器,即使是在生产环境中,并通过http服务器上传文件,这将不太理想。

xe55xuns

xe55xuns7#

大家好!这个问题有什么新进展吗?

像大多数人一样,我也被这个链接:https://github.com/electron/electron/blame/80f89a34728281cc61cfacd7b682f0227f89a102/docs/api/protocol.md#L101-L104 弄得有些困惑。我认为自定义协议的文档应该明确指出不支持cookie。

理想情况下,应该有一些关于如何设置一些常见场景的示例。例如,在我的案例中,我试图打包一个使用React编写的单页应用程序,该应用程序访问远程后端。后端具有适当的CORS和CSRF(期望客户端设置一个带有从cookie读取的内容的头部)。

根据我在网上找到的一些提示,我能够使用webRequest.onHeadersReceivedwebRequest.onBeforeSendHeaders调整应用程序中的CORS后端设置。因此,使用file://协议的所有GET请求都能正常工作。经过一些调查,从文档中我发现,添加一个自定义协议并将其注册为标准协议将允许我完全替换http协议......但在几次尝试后,我意识到无法设置cookie。即使从控制台运行

window.cookieStore.set('key', 'value');

,结果也是:

Uncaught (in promise) DOMException: An unknown error occurred while writing the cookie.

因此,我决定寻找一个bug(我认为这是一个bug,因为文档明确指出,作为标准注册的自定义协议可以实现替换http协议的目的)。

除了定义自己的自定义方案之外,我还尝试拦截http协议protocol.interceptFileProtocol('http', handler),它似乎起作用了,使用的处理程序与我在protocol.registerFileProtocol('app', handler)中使用的完全相同。这种方法有潜在的问题吗?

相关问题