Electron SDK
Electron SDK 完全在 主行程 執行,透過作業系統原生視窗顯示驗證碼 UI。渲染行程不會參與驗證流程——為了安全請保持這種隔離。
GitHub 上的範例
📦
Captcha-La/electron-demo — 完整可執行範例,包含所有整合步驟。
安裝
npm install @captchala/electronThe package targets Electron 28+ (the demo pins ^33.0.0) and Node 18+. Run the demo end-to-end with:
npm install
npm start快速開始
// main.js (Electron main process — never the renderer)
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const { CaptchalaClient } = require('@captchala/electron');
let currentClient = null;
ipcMain.handle('verify', async (event, opts) => {
// 1. Fetch a one-shot server_token from YOUR backend.
const serverToken = await fetchServerTokenFromYourBackend(opts.action);
// 2. Tear down any prior client, then build a fresh one.
if (currentClient) { currentClient.destroy(); currentClient = null; }
currentClient = new CaptchalaClient({
appKey: 'YOUR_APP_KEY',
serverToken,
action: opts.action, // 'login' | 'register' | 'pay' | …
lang: opts.lang, // 'en' | 'zh-CN' | 'ja' | …
theme: opts.theme, // 'light' | 'dark'
timeoutMs: 15000,
retryCount: 3,
onReady: () => event.sender.send('captcha-status', 'ready'),
onFail: (e) => event.sender.send('captcha-status', `recoverable: ${e.code}`),
});
try {
const result = await currentClient.verify();
// Send result.passToken to YOUR backend for validation.
return { success: true, passToken: result.passToken };
} catch (err) {
return { success: false, error: err.message };
} finally {
if (currentClient) { currentClient.destroy(); currentClient = null; }
}
});
function createWindow() {
const win = new BrowserWindow({
width: 520, height: 640, resizable: false,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
});
win.loadFile('index.html');
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => app.quit());// preload.js — bridge the renderer to the main-process verify().
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('captchala', {
verify: (opts) => ipcRenderer.invoke('verify', opts),
onStatus: (callback) => ipcRenderer.on('captcha-status', (_, msg) => callback(msg)),
});API 一覽
| 符號 | 用途 |
|---|---|
new CaptchalaClient({...}) | 建立一次性客戶端。傳入 appKey、serverToken、action、lang、theme、timeoutMs、retryCount,以及事件處理函式。 |
await client.verify() | 開啟原生驗證碼視窗。成功時 resolve 回傳結果,硬錯誤時 reject。 |
onReady / onFail | 可選的建構子回呼。onFail 表示 可恢復 的失敗(SDK 會自動重試)。 |
result.passToken | 用於伺服器端驗證的 token,對客戶端始終為不透明字串。 |
client.destroy() | 關閉視窗並釋放資源。每個 client 實例使用完畢後都應呼叫。 |
CaptchalaClient.version() | 靜態方法,回傳 SDK 版本字串。適合放在支援 / 除錯浮層中。 |
伺服器端驗證
將 result.passToken(或 result.token)送到你的後端,再呼叫 CaptchaLa API 驗證。切勿在用戶端程式碼中暴露 X-App-Secret。
POST https://apiv1.captcha.la/v1/validate
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json
{ "pass_token": "<result.passToken>", "client_ip": "<end-user IP>" }完整驗證端點及 X-App-Key / X-App-Secret 流程請見 API 參考。
常見問題
不要在 renderer 中 import SDK
@captchala/electron僅能在主行程使用。如同 demo 的preload.js,透過contextBridge+ipcRenderer.invoke()暴露結果。維持nodeIntegration: false、contextIsolation: true。執行時找不到模組
@captchala/electron應放在dependencies(不是devDependencies),必須打包進最終應用。electron-builder 等工具會自動包含。驗證碼視窗出現在主視窗後面
這是 Linux/X11 的常見問題。如果你包了一層BrowserWindow,傳入parent;或在verify()回傳後呼叫mainWindow.focus()。需要 Electron 28+
demo 中宣告electron: ^33.0.0。較舊的 Electron 缺少 SDK 依賴的 API;請鎖定28+與 Node 18+。
系統需求
- Electron 28+ (the demo uses 33.x)
- Node 18+
- Cross-platform: macOS, Windows 10 1809+, Linux (X11 / Wayland)