跳到主内容

Electron app

casdoor-electron-example展示了在 Electron 应用中使用 Casdoor 登录(自定义协议 + 浏览器 OAuth)。

运行示例

初始化

设置这6个字符串参数:

名称描述路径
serverUrl您的Casdoor服务器URLsrc/App.js
clientid您的Casdoor应用程序的客户端IDsrc/App.js
appName您的Casdoor应用程序的名称src/App.js
redirectPath如果未提供,您的Casdoor应用程序的重定向URL路径将为/callbacksrc/App.js
clientSecret您的Casdoor应用程序的客户端密钥src/App.js
casdoorServiceDomain您的Casdoor服务器URLpublic/electron.js

默认值:Casdoor演示app-casnode未设置时使用。

命令

在项目目录中:

npm run dev 或者 yarn dev

构建电子应用并运行此应用。

npm run make 或者 yarn make

打包并分发您的应用程序。 它将创建 out 文件夹,您的软件包将被定位于:

// macOS下的out/示例  
├── out/make/zip/darwin/x64/casdoor-electron-example-darwin-x64-1.0.0.zip
├── ...
└── out/casdoor-electron-example-darwin-x64/casdoor-electron-example.app/Contents/MacOS/casdoor-electron-example

预览

Electron 登录

运行应用会打开一个窗口。 点击使用Casdoor登录以在浏览器中打开Casdoor登录页面。

浏览器视图

登录后,应用将打开并显示您的用户名。

Electron 注销 Electron 预览 Gif

集成步骤

1. 设置自定义协议

注册casdoor自定义协议:

const protocol = "casdoor";

if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient(protocol, process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
app.setAsDefaultProtocolClient(protocol);
}

然后,浏览器可以打开您的应用,并通过该协议传递授权码。

2. 在浏览器中打开登录URL

const serverUrl = "https://door.casdoor.com";
const appName = "app-casnode";
const redirectPath = "/callback";
const clientId = "014ae4bd048734ca2dea";
const clientSecret = "f26a4115725867b7bb7b668c81e1f8f7fae1544d";

const redirectUrl = "casdoor://localhost:3000" + redirectPath;

const signinUrl = `${serverUrl}/login/oauth/authorize?client_id=${clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUrl)}&scope=profile&state=${appName}&noRedirect=true`;

shell.openExternal(signinUrl); //在浏览器中打开登录网址

为您的Casdoor实例调整前五个变量。

3. 监听应用打开事件

在浏览器中登录后,浏览器会通过自定义协议打开您的应用。 监听该事件:

const gotTheLock = app.requestSingleInstanceLock();
const ProtocolRegExp = new RegExp(`^${protocol}://`);

if (!gotTheLock) {
app.quit();
} else {
app.on("second-instance", (event, commandLine, workingDirectory) => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
commandLine.forEach((str) => {
if (ProtocolRegExp.test(str)) {
const params = url.parse(str, true).query;
if (params && params.code) {
store.set("casdoor_code", params.code);
mainWindow.webContents.send("receiveCode", params.code);
}
}
});
}
});
app.whenReady().then(createWindow);

app.on("open-url", (event, openUrl) => {
const isProtocol = ProtocolRegExp.test(openUrl);
if (isProtocol) {
const params = url.parse(openUrl, true).query;
if (params && params.code) {
store.set("casdoor_code", params.code);
mainWindow.webContents.send("receiveCode", params.code);
}
}
});
}

授权码位于casdoor_code</code>或params.code。

4. 用代码兑换用户信息

async function getUserInfo(clientId, clientSecret, code) {
const { data } = await axios({
method: "post",
url: authCodeUrl,
headers: {
"content-type": "application/json",
},
data: JSON.stringify({
grant_type: "authorization_code",
client_id: clientId,
client_secret: clientSecret,
code: code,
}),
});
const resp = await axios({
method: "get",
url: `${getUserInfoUrl}?accessToken=${data.access_token}`,
});
return resp.data;
}

ipcMain.handle("getUserInfo", async (event, clientId, clientSecret) => {
const code = store.get("casdoor_code");
const userInfo = await getUserInfo(clientId, clientSecret, code);
store.set("userInfo", userInfo);
return userInfo;
});

请参阅OAuth了解完整流程。