繁体   English   中英

Electron - 如何从 BrowserWindow 获取授权令牌到主 Electron 应用程序

[英]Electron - how to get an auth token from BrowserWindow to the main Electron App

我有一个 Angular Electron 应用程序,它使用 BrowserWindow 使用第三方 OpenID Connect 身份提供程序登录。 此外,我有自己的实现 OpenID Connect 标准的后端。 后端在localhost:5000下运行。

Package 版本:

Angular:11.1.0
electron:9.1.0
ngx-电子:2.2.0

流程是这样的:

  • Electron 打开一个带有localhost:5000/connect/authorize的 BrowserWindow 为 URL(包括所需的查询参数)
  • 后端重定向到第三方身份提供者
  • 用户登录
  • 第三方使用身份验证信息重定向到后端
  • 后端重定向到提供的 returnUri(前端回调)
  • BrowserWindow 调用回调 function 并在 URL 中具有身份验证令牌(如预期的那样)

--> 如何将身份验证令牌从 BrowserWindow 获取到主 Electron 应用程序? 实际上,我需要在主 Electron 应用程序中调用回调 function

登录逻辑,在主 Electron 应用程序中调用:

public login() {
  // Everything in here is called in the main Electron app

  const authWindow = new this.electron.remote.BrowserWindow({
      width: 800, 
      height: 600, 
      show: false, 
      webPreferences: {
        nodeIntegration: false,
        webSecurity: false
      }
    });

    authWindow.loadURL(myAuthurl);
    authWindow.show();
    authWindow.webContents.openDevTools();

    const defaultSession = this.electron.remote.session.defaultSession;

    const { session: { webRequest } } = authWindow.webContents; 

    webRequest.onBeforeRequest(null, async request => {
      console.log(request);
    });

    webRequest.onBeforeRedirect(null, async request => {
      console.log(request); // Callback function never called

    });

    defaultSession.webRequest.onBeforeRequest(null, async request => {
      console.log(request); // Callback function never called
    });

    defaultSession.webRequest.onBeforeRequest(null, request => {
      console.log(request); // Callback function never called
    });


    defaultSession.webRequest.onBeforeRedirect(null, request => {
      console.log(request); // Callback function never called
    });

    authWindow.on('closed', (event) => {
      console.log(event); // Callback function called when the window is closed but with no data
    });
}

回调逻辑,在 BrowserWindow 中调用(但它是同一个 Angular 应用程序):

// this method is called after successful log in
// here I'm still in the BrowserWindow

public callback()
  // here's the data I need. How do I "send" this data to the main Electron app?
  const hash = window.location.hash;
} 

编辑:我尝试ipcRenderer ,但从未触发on回调:

// executed in the main Electron app
const ipc = this.electron.ipcRenderer;

ipc.on('authtoken', (event, arg) => {
  console.log(arg);
})

ipc.send('authtoken', 'DATA');

关于我在这里缺少什么的任何想法? 有更好的方法吗?

了解 Electron 的工艺 model 很重要,因为在第一次使用时正确操作可能非常复杂且具有挑战性。 因此,我推荐阅读 Electron 的进程 model 文档以及进程间通信的官方 IPC 教程。

在您的情况下,您必须将令牌从 Renderer 进程发送到您存储它的主进程(或使用它做任何您想做的事情)。 这是使用ipcRenderer.send()中的BrowserWindow ipcMain.on()和 Main 进程中的 ipcMain.on() 来完成的。

// BrowserWindow doing the authentication stuff
const { ipcRenderer } = require ("electron");

ipcRenderer.send ("authtoken", "DATA");

和主要过程中的对应物:

// Where your imports are
const { ipcMain } = require ("electron");

// ...

ipcMain.on ("authtoken", (event, arg) => {
    // arg will be the data you sent from the auth window
});

如果您从主进程中打开身份验证 window,我建议存储对它的引用,例如let authwindow = new BrowserWindow(...)以便您可以在使用authwindow.destroy()

但是,如果您不这样做,而是从另一个BrowserWindow打开 window,您仍然可以向第一个 window 发送事件,因为您在主进程中有对它的引用。 例如:

// Main process, where you create the initial window
// Where your imports are
const { ipcMain } = require ("electron");

// ...
let mainWindow = new BrowserWindow (/* ... */);

ipcMain.on ("authtoken", (event, arg) => {
    // arg will be the data you sent from the auth window
    mainWindow.webContents.send ("close-auth");
});

并在主 window 中接收此事件并关闭身份验证 window:

// Main window
const { ipcRenderer } = require ("electron");

public login() {
  // Everything in here is called in the main Electron app

  const authWindow = new this.electron.remote.BrowserWindow({
      width: 800, 
      height: 600, 
      show: false, 
      webPreferences: {
        nodeIntegration: false,
        webSecurity: false
      }
    });

    authWindow.loadURL(myAuthurl);
    authWindow.show();
    authWindow.webContents.openDevTools();

    const defaultSession = this.electron.remote.session.defaultSession;

    ipcRenderer.once ("close-auth", (event, arg) => { authWindow.destroy (); });
}

(如果回调 function 已经运行一次, #once()将导致后续信号被忽略。如果再次调用login() ,它将再次注册并按预期工作,但如果我们使用了#on() ,我们会增长每个 function 调用的注册侦听器数量。 #once()也可在ipcMain上使用,但不应该经常需要。)

最后一个快速说明: remote已弃用,因此我建议从主进程打开身份验证 window,删除remote并执行从主进程remote所需的所有工作,通过 IPC 与不同的BrowserWindows通信,就像我向你展示的那样这里。

另外,我建议不要在导入时重命名 Electron 包; 如果您在所有进程上下文中调用 IPC package ipc ,您迟早会感到困惑。 如果您保留ipcMainipcRenderer ,那么您应该立即清楚您属于哪种进程,如果您选择稍后重构您的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM