簡體   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