electron 에서 preload.js 를 올바로 사용해야 하는 이유는 보안 때문 입니다.
renderer 에서 require 를 사용해서 시스템에 직접 접근하는 것은 보안상 매우 위험해 질 수 있습니다.
IPC(프로세스간통신) 을 통해 renderer 와 main process 를 분리하고, main 에서는 검증된 요청만 처리해야 더욱 안전한 프로그래밍이 가능 해 집니다.
main.js
const {app, BrowserWindow, ipcMain } = require("electron");
let win;
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false, // is default value after Electron v5
contextIsolation: true, // protect against prototype pollution
enableRemoteModule: false, // turn off remote
preload: app.getAppPath()+"/preload.js" // use a preload script
}
});
win.webContents.openDevTools() //랜더러에서 console창 보여주기
win.loadFile(app.getAppPath()+"/index.html");
}
app.on("ready", createWindow);
ipcMain.on("toMain", (event, data) => {
console.log(`Received [${data}] from renderer browser`);
win.webContents.send("fromMain", ' here is main! ');
});
preload.js
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld(
"api", {
send: (channel, data) => {
let validChannels = ["toMain"]; // IPC채널들 추가
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel, func) => {
let validChannels = ["fromMain"]; // IPC채널들 추가
if (validChannels.includes(channel)) {
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
}
}
);
index.html
<!doctype html>
<html lang="en-US">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta charset="utf-8"/>
<title>Title</title>
</head>
check browser console and terminal console
<body>
<script>
window.api.receive("fromMain", (data) => {
console.log(`Received [${data}] from main process`);
});
window.api.send("toMain", "here is renderer");
</script>
</body>
</html>
설명
브라우저에서 window.api.receive() 에서 나중에 받을 준비를 해 놓는다.
브라우저에서 window.api.send() 에서 preload의 contextBridge 속 api.send 함수를 호출한다.
contextBridge.api.send 에서는 IPC 통신을 통해 main 으로 호출을 전달한다.
main 의 ipcMain.on("toMain",..) 에서 값을 받아 처리한 뒤 win.webContents.send() 를 사용해서 브라우저로 결과를 반환한다.
preload의 contextBridge 속 api.receive 함수에서는 main 에서 받은 값을 브라우저로 전달한다.
브라우저의 api.receive 함수가 호출되어 결과값을 console에 출력한다.
결과화면
출처 : github.com/electron/electron/issues/9920#issuecomment-575839738
출처 : www.javaer101.com/ko/article/2206718.htmlgithub.com/reZach/secure-electron-template/blob/master/docs/secureapps.md
'프론트엔드 개발 놀이터 > electron' 카테고리의 다른 글
electron 에서 express 쓰기 (electron-router) (0) | 2020.11.11 |
---|---|
Electron - 일렉트론+뷰 로 우아한 데스크탑 앱 만들기 기초 (0) | 2020.09.27 |