跳到主要内容

版本:5.X

Electron 上下文隔离

什么是上下文隔离?

上下文隔离(Context Isolation) 是 Electron 中一项重要的安全特性,它确保您的预加载脚本(preload.js)和 Electron 内部逻辑,运行在加载的网页(webContents)之外的独立上下文环境中。

这项机制能有效防止网页内容访问 Electron 内部模块或您在预加载脚本中暴露的高权限 API,进一步提升应用的安全性。

换句话说,预加载脚本中的 window 对象,与网页中的 window 是两个不同的环境

例如:

javascript
// preload.js
window.hello = 'wave'

如果启用了上下文隔离,网页中执行 window.hello,将会返回 undefined,无法访问到预加载脚本中的变量

提示

Electron 12 起,上下文隔离默认启用,并且是官方强烈推荐的安全配置。 更多详细说明可参考:Electron 官方文档

Electron 中的上下文隔离适配方案

step 1: 主进程初始化

在主进程中,初始化 BrowserWindow 时,需要在 webPreferences 中设置:

  • contextIsolation: true
  • 指定 preload.js 路径
javascript
// main.js
const { app, BrowserWindow } = require('electron')
const RCInit = require('@rongcloud/electron')

let rcService

app.on('ready', () => {
// 在 app 的 ready 事件通知后进行初始化
rcService = RCInit({
/**
* 【必填】Appkey , 自 5.6.0 版本起,必须填该参数
* [option]
*/
appkey: '<appkey>',
/**
* 【选填】消息数据库的存储位置,不推荐修改
* [option]
*/
dbPath: app.getPath('userData'),
/**
* 【选填】日志等级
* [option] 4 - DEBUG, 3 - INFO, 2(default) - WARN, 1 - ERROR
*/
logOutputLevel: 2,
/**
* 【选填】是否同步空的置顶会话,默认值为 `false`
* [option]
*/
enableSyncEmptyTopConversation: false
})

// 初始化 UI 窗口
const browserWin = new BrowserWindow({
webPreferences: {
// 指定预加载的 preload.js 文件,在其中引用 @rongcloud/electron-renderer
preload: '<path/to/preload.js>',
// Electron 开启上下文隔离
contextIsolation: true,
nodeIntegration: true
}
})

app.on('before-quit', () => {
// 在 app 退出时清理状态
rcService.destroy()
})
})

step 2: 在 preload.js 中导入 SDK

@rongcloud/electron-renderer 以及 initContextBridge 操作放在 preload.js 中:

javascript
// preload.js
const renderer = require('@rongcloud/electron-renderer');
renderer.initContextBridge()

step 3: 渲染进程使用

  • 初始化渲染进程 initRenderer
  • 在渲染进程导入 IMLib SDK
javascript
// 渲染进程 index.js

import { initRenderer } from '@rongcloud/electron-renderer/renderer';
initRenderer();

// 应用初始化,请务必保证此过程只被执行一次
import RongIMLib from '@rongcloud/imlib-next'

RongIMLib.init({ appkey: '<Your-App-Key>' });

// 添加事件监听
const Events = RongIMLib.Events

RongIMLib.addEventListener(Events.CONNECTING, () => {
console.log('正在连接服务器')
})

RongIMLib.addEventListener(Events.CONNECTED, () => {
console.log('已经连接到服务器')
})

RongIMLib.addEventListener(Events.MESSAGES, (evt) => {
console.log(`收到消息:${evt.messages}`)
})

//建立连接
RongIMLib.connect('<Your-Token>').then(res => {
if (res.code === RongIMLib.ErrorCode.SUCCESS) {
console.log('连接成功, 连接用户 id 为: ', res.data.userId);
} else {
console.warn('连接失败, code:', res.code)
}
})