You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron技术问题:如何将BrowserWindow中的Auth Token传递至主进程

Angular Electron应用:将BrowserWindow的Auth Token传递至主进程

依赖包版本

  • Angular: 11.1.0
  • Electron: 9.1.0
  • ngx-electron: 2.2.0

登录流程

  1. Electron打开BrowserWindow,加载授权地址localhost:5000/connect/authorize(含必要查询参数)
  2. 后端重定向至第三方身份提供商
  3. 用户完成登录操作
  4. 第三方提供商携带认证信息重定向至后端
  5. 后端重定向至指定的前端回调地址(returnUri)
  6. 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');

问题分析

  1. IPC使用错误:主进程应使用ipcMain监听事件,ipcRenderer仅用于渲染进程发送消息,你在主进程中调用ipcRenderer.on是无效的。
  2. webRequest监听失效:通过remote获取session时,因nodeIntegration: false导致权限不足,且onBeforeRedirect仅在重定向阶段触发,最终回调地址可能是直接加载而非重定向,因此未触发。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:01:28