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)
}
})