使用 Google OAuth 的 Electron 应用程序:“此浏览器或应用程序可能不安全”

Paw*_*tyć 11 google-oauth electron

我的应用程序的一位用户今天报告了有关向 Google 授权用户(使用 OAuth 2.0)的问题。到目前为止,应用程序正在打开一个新的浏览器窗口(节点集成已禁用,会话与主应用程序分离)。你可以在这里看到实现,因为该库是 OSS。我用它来授权用户访问 Google Drive 上的应用程序数据。今天登录后看到以下消息:

此浏览器或应用程序可能不安全。

尝试使用不同的浏览器。如果您已经在使用受支持的浏览器,您可以刷新屏幕并再次尝试登录。

了解更多链接有一个面向开发人员的部分。本节有 2 个链接。一是如何将应用程序升级到PWA。由于该应用程序是一个 API 测试工具,因此无法在 Web 浏览器中运行它。第二个链接指向描述如何迁移到本机应用程序授权的文档。然而,所描述的流程需要授权码授权。这意味着我需要将 OAuth 机密包含到我的应用程序中。然而,Electron 应用程序仍然是 Web 应用程序,并且没有编译源代码的概念。我会将不安全的客户秘密暴露给公众。我可能可以构建一个服务器应用程序来支持它,但该应用程序是 OSS 项目。它没有资金来运行授权服务器。

我现在的问题是我应该如何为 Electron 应用程序实现 OAuth 2。在这种情况下,我无法使用 PWA,并且服务器授权流程(代码授予)远非理想。

小智 17

作为帕维?解释说,改变用户代理就行了。但是,您可以通过在加载 URL 时传递一个对象来轻松设置用户代理

win = new BrowserWindow({width: 800, height: 600});
win.loadURL(authUrl, {userAgent: 'Chrome'})
Run Code Online (Sandbox Code Playgroud)

我已经测试过它,它就像一个魅力

  • 先生,您真是个天才! (3认同)

Ven*_*ryx 12

警告:此答案依赖于更改浏览器的用户代理。截至 2021 年 1 月,Google 不同意此做法并警告不要这样做(请参阅 EDIT4)。使用风险自负!

其他答案对我不起作用(在 Electron 9.0.5 中),但我最终找到了这个,它起作用了:

app.on("ready", ()=> {
    session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
        details.requestHeaders["User-Agent"] = "Chrome";
        callback({ cancel: false, requestHeaders: details.requestHeaders });
    });

    CreateMainWindow(); // your regular code to create root browser window
});
Run Code Online (Sandbox Code Playgroud)

编辑:另外两种方法,我还没有测试过,但也可能有效:

app.on("ready", ()=>{
    session.defaultSession.setUserAgent("Chrome");
    ...
}
Run Code Online (Sandbox Code Playgroud)
app.userAgentFallback = "Chrome";
Run Code Online (Sandbox Code Playgroud)

EDIT2:稍后再试,方法#2 不起作用,但#1 仍然有效。还没试过#3。

EDIT3:稍后再试,似乎不再需要这些解决方法了!Google 似乎再次接受来自 Electron 应用程序的登录弹出窗口,而无需修改用户代理。(奇怪的是他们会恢复这个;也许我在重新尝试时做错了什么)

EDIT4:虽然方法 #1 仍然适用于 atm,但我最近发现了这篇博文:https : //developers.googleblog.com/2020/08/guidance-for-our-effort-to-block-less-secure-browser-and -apps.html显然,从 2021 年 1 月开始,Google 将限制在非标准浏览器(可能包括 Electron)中使用 Google 登录,并警告开发人员不要修改他们浏览器的用户代理(这三种可能性我提到做)。使用风险自负!(他们没有说明会产生什么结果,但为了我自己的使用,从现在开始我选择使用下面显示的替代方案)


作为在您的应用程序中使用 Google 登录弹出窗口的替代方案(有些人可能会担心,因为 Electron 应用程序原则上可以将代码插入弹出窗口以读取原始密码——并不是那么重要,因为 Electron 应用程序无论如何都可以安装键盘记录器等),您可以改为在用户的常规外部浏览器中打开一个选项卡,指向一个特殊页面,在那里触发登录弹出窗口,然后将凭据发送到您的 Electron 应用程序。

说明可以在这里看到(方法3):https : //stackoverflow.com/a/64328193/2441655


Paw*_*tyć 4

经过大胆猜测后,我决定更改用户代理字符串并从中删除应用程序名称以及Electron/版本。进行此更改后,它再次开始工作。

实施示例:

const win = new BrowserWindow(params);
let ua = win.webContents.userAgent;
ua = ua.replace(/APPLICATION NAME HERE\/[0-9\.-]*/,'');
ua = ua.replace(/Electron\/*/,'');
win.webContents.userAgent = ua;
Run Code Online (Sandbox Code Playgroud)

这假设应用程序使用 symver 并且没有预发布标签。否则你将不得不稍微调整正则表达式。