Casdoor的Electron应用示例
一个Electron应用示例,演示了Casdoor的集成能力。
如何运行示例
初始化
您需要初始化6个参数,所有这些参数都是字符串类型:
名称 | 描述 | 路径 |
---|---|---|
serverUrl | 您的Casdoor服务器URL | src/App.js |
clientid | 您的Casdoor应用程序的客户端ID | src/App.js |
appName | 您的Casdoor应用程序的名称 | src/App.js |
redirectPath | 如果未提供,您的Casdoor应用程序的重定向URL路径将为/callback | src/App.js |
clientSecret | 您的Casdoor应用程序的客户端密钥 | src/App.js |
casdoorServiceDomain | 您的Casdoor服务器URL | public/electron.js |
如果您没有设置这些参数, 此项目将使用 Casdoor 在线演示 作为默认的Casdoor 服务器,并使用 Casnode 作为默认的 Casdoor 应用程序。
可用命令
在项目目录中,您可以运行:
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应用程序,一个新的窗口将会出现在你的桌面上。 如果你点击Login with Casdoor
按钮,你的默认浏览器将自动打开并显示登录页面。 登录成功后,您的Electron应用程序将会打开,并且您的用户名将会在您的应用程序上显示。 您可以在下面的gif图像中预览整个过程。
集成步骤
设置自定义协议
首先,您需要设置自定义协议名为 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);
}
这将允许浏览器打开你的电子应用程序并将登录信息发送到电子应用程序。
在浏览器中打开登录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); //在浏览器中打开登录网址
您可以更改前五个参数。
监听开启的应用程序事件
一旦您通过浏览器成功登录,浏览器将打开您的Electron应用程序。 因此,你必须监听开放应用程序事件。
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);
}
}
});
}
您可以从broswer获取代码,即casdoor_code
或params.code
。
解析代码并获取用户信息
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文档页面获取用户信息。