Electron技术问题:如何将BrowserWindow中的Auth Token传递至主进程
Angular Electron应用:将BrowserWindow的Auth Token传递至主进程
依赖包版本
- Angular: 11.1.0
- Electron: 9.1.0
- ngx-electron: 2.2.0
登录流程
- Electron打开BrowserWindow,加载授权地址
localhost:5000/connect/authorize(含必要查询参数) - 后端重定向至第三方身份提供商
- 用户完成登录操作
- 第三方提供商携带认证信息重定向至后端
- 后端重定向至指定的前端回调地址(returnUri)
- BrowserWindow加载回调地址,URL中包含所需的Auth Token
问题
需要将BrowserWindow中的Auth Token传递至Electron主进程,且回调逻辑希望在主进程中执行。
当前代码
主进程登录逻辑
public login() { // 以下代码运行在Electron主进程 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); // 回调从未触发 }); defaultSession.webRequest.onBeforeRequest(null, async request => { console.log(request); // 回调从未触发 }); defaultSession.webRequest.onBeforeRedirect(null, request => { console.log(request); // 回调从未触发 }); authWindow.on('closed', (event) => { console.log(event); // 窗口关闭时触发,但无数据 }); }
BrowserWindow回调逻辑(Angular应用内)
// 登录成功后触发此方法,当前仍在BrowserWindow环境中 public callback() { // 这里是需要的token数据 const hash = window.location.hash; }
IPCRenderer尝试失败代码
// 运行在Electron主进程 const ipc = this.electron.ipcRenderer; ipc.on('authtoken', (event, arg) => { console.log(arg); }); ipc.send('authtoken', 'DATA');
问题分析
- IPC使用错误:主进程应使用
ipcMain监听事件,ipcRenderer仅用于渲染进程发送消息,你在主进程中调用ipcRenderer.on是无效的。 - webRequest监听失效:通过
remote获取session时,因nodeIntegration: false导致权限不足,且onBeforeRedirect仅在重定向阶段触发,最终回调地址可能是直接加载而非重定向,因此未触发。 - remote模块滥用:在渲染进程中用
remote创建BrowserWindow会增加跨进程通信开销,建议直接在主进程中管理窗口。
解决方案
方案一:主进程直接监听URL变化(推荐,符合回调逻辑在主进程执行的需求)
无需渲染进程处理,主进程通过监听BrowserWindow的导航事件,直接解析回调URL中的Token:
// 主进程代码(main.js) const { BrowserWindow } = require('electron'); function login() { const authWindow = new BrowserWindow({ width: 800, height: 600, show: false, webPreferences: { nodeIntegration: false, contextIsolation: true, // Electron 9默认false,建议开启提升安全性 webSecurity: false } }); // 替换为你的授权地址(带查询参数) const myAuthUrl = 'http://localhost:5000/connect/authorize?client_id=xxx&redirect_uri=http://localhost:4200/callback&response_type=token'; authWindow.loadURL(myAuthUrl); authWindow.show(); authWindow.webContents.openDevTools(); // 监听页面导航事件 authWindow.webContents.on('will-navigate', (event, url) => { handleAuthCallback(url, authWindow); }); // 处理hash模式的回调(页面加载完成后检查URL) authWindow.webContents.on('did-finish-load', () => { const currentUrl = authWindow.webContents.getURL(); handleAuthCallback(currentUrl, authWindow); }); authWindow.on('closed', () => { // 清理窗口引用 authWindow = null; }); } function handleAuthCallback(url, authWindow) { // 替换为你的实际回调地址前缀 const callbackUrlPrefix = 'http://localhost:4200/callback'; if (url.startsWith(callbackUrlPrefix)) { // 解析URL中的hash参数 const hashParams = new URLSearchParams(url.split('#')[1]); const authToken = hashParams.get('access_token'); // 根据实际字段名调整 const idToken = hashParams.get('id_token'); if (authToken) { console.log('获取到Auth Token:', authToken); // 这里可以添加Token处理逻辑:保存到本地存储、通知主窗口等 authWindow.close(); // 关闭认证窗口 } } }
方案二:渲染进程通过IPC传递Token
如果需要渲染进程先处理Token,再传递给主进程:
主进程代码
// 主进程main.js const { ipcMain } = require('electron'); // 监听渲染进程发来的Token ipcMain.on('send-auth-token', (event, tokenData) => { console.log('主进程收到Token:', tokenData); // 处理Token逻辑:保存、验证等 });
Angular渲染进程代码
import { ElectronService } from 'ngx-electron'; constructor(private electronService: ElectronService) {} public callback() { const hash = window.location.hash; const hashParams = new URLSearchParams(hash.slice(1)); const authToken = hashParams.get('access_token'); if (this.electronService.isElectronApp && this.electronService.ipcRenderer) { // 发送Token到主进程 this.electronService.ipcRenderer.send('send-auth-token', { accessToken: authToken, idToken: hashParams.get('id_token') }); // 关闭当前认证窗口 window.close(); } }
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

