Desktop SSO Integration
To integrate the Skillmine Auth login page into a desktop application, you can use either of the following authentication flows:
Browser-Based Authorization Flow
Device Authorization Flow
Each flow requires setting up your client in the Skillmine Auth admin portal first.
🛠️ Prerequisites
Before starting integration:
Go to the Skillmine Auth Admin Portal.
Create the Client Settings and Blueprint Configuration using the below documentation:
Note down the generated
client_id
,client_secret
(if applicable), and thebaseurl
of your auth instance.
🌐 Option 1: Browser-Based Authorization Flow
In this method, your desktop app opens the Skillmine Auth login page in the user's default browser and handles the authentication callback.
🔗 Step 1: Generate Authorization URL
Build an authorization URL using the following structure:
{{baseurl}}/authz-srv/authz?
client_id=YOUR_CLIENT_ID
&response_type=token
&scope=openid%20profile%20user_info_all
&redirect_uri=YOUR_DESKTOP_REDIRECT_URL
&groups_info=0
&response_mode=query
🔁 Replace placeholders:
client_id
: From Skillmine Auth admin portalredirect_uri
: URL your app listens to for the redirect (can be a custom scheme likemyapp://callback
for native apps)
🖥️ Step 2: Open in Browser
When your desktop app launches and no session is active:
Open the authorization URL in the user's browser.
After successful login, the user will be redirected to your app’s redirect URI with either an
access_token
or an authorizationcode
.
🔐 Step 3: Token Handling
If you use
response_type=code
, exchange the code for a token by calling the Token API.If you use
response_type=token
, the token will be returned directly in the redirect URL.
🔄 Step 4: Session Maintenance
Periodically call the Introspection API to check token validity.
On logout, call the Logout API to properly terminate the session.
📘 Well-Known Endpoint
Fetch available endpoints (token URL, logout URL, etc.):
bashCopyEdit{{api_base_url}}/.well-known/openid-configuration
This JSON provides all the necessary URLs for token exchange, introspection, and logout.
🖥️ Option 2: Device Authorization Flow
This flow is ideal for native desktop apps without embedded browsers or with limited input capabilities.
📲 Step 1: Request Device Code
Call the Device Authorization Endpoint with your client_id
and required scope
. The response will look like:
{
"device_code": "2fa60989-a880-40b0-a7d1-42c973ff6b51",
"user_code": "30CATn",
"verification_uri": "{{api_base_url}}/device/verify",
"verification_uri_complete": "{{api_base_url}}/device/verify?user_code=30CATn",
"expires_in": 8600,
"interval": 5
}
💻 Step 2: Display Info to User
Show the following to the user:
A link to open (
verification_uri_complete
)A
user_code
they may need to enter
The user will open the link in a browser, log in via Skillmine Auth, and enter the code if required.
🔁 Step 3: Poll for Status
In the background, your app must poll the Verification Status Endpoint:
POST {{baseurl}}/device/code/verification
Body:
{
"device_code": "2fa60989-a880-40b0-a7d1-42c973ff6b51"
}
Poll at intervals specified in the response (interval: 5
seconds).
Possible Responses
While Waiting:
{
"success": false,
"code": 400,
"error": {
"error": "authorization_pending",
"error_description": "The provided authorization grant is invalid : authorization_pending"
}
}
On Success:
{
"success": true,
"code": 200,
"data": {
"is_validated": true,
"validated_time": "2025-06-10T08:06:43.284Z"
}
}
✅ Step 4: Proceed to Dashboard
Once authentication is successful, your app can redirect the user to the main dashboard or start using the token.
Sample : Desktop SSO Integration with Electron using Skillmine Auth
This guide explains how to implement Single Sign-On (SSO) in an Electron-based desktop application using Skillmine Auth, with token-based authentication and user info retrieval.
🧱 Prerequisites
Access to Skillmine Auth Admin Portal
Valid
client_id
andredirect_uri
Node.js v14+ and Electron installed
Install dependencies
npm install electron open express axios
⚙️ Step 1: Configure Skillmine Auth
➔ Client Settings
Create a new client in the Skillmine Auth admin panel:
Allowed Grant Types:
authorization_code
,implicit
Redirect URI:
http://localhost:3000/callback
Scopes:
openid profile user_info_all
Response Types:
token
(orcode
)
📎 Docs: Client Settings
📂 Step 2: Sample Electron Code
1. main.js (Electron main process)
const { app, BrowserWindow } = require('electron');
const express = require('express');
const http = require('http');
const url = require('url');
const axios = require('axios');
const path = require('path');
const open = require('open').default;
const CLIENT_ID = 'your-client-id';
const REDIRECT_URI = 'http://localhost:3000/callback';
const AUTH_BASE_URL = 'https://your-skillmine-auth.com';
const SCOPE = 'openid profile user_info_all';
let mainWindow;
function createMainWindow(userName) {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
}
});
mainWindow.loadFile('index.html');
mainWindow.webContents.on('did-finish-load', () => {
mainWindow.webContents.send('user-welcome', userName);
});
}
function startSSOFlow() {
const expressApp = express();
const server = http.createServer(expressApp);
expressApp.get('/callback', async (req, res) => {
const parsedUrl = url.parse(req.url, true);
const accessToken = parsedUrl.query.access_token;
try {
const userinfoUrl = `${AUTH_BASE_URL}/authz-srv/userinfo`;
const response = await axios.get(userinfoUrl, {
headers: { Authorization: `Bearer ${accessToken}` }
});
const userName = response.data.name || response.data.preferred_username || 'User';
res.send('<h2>Login successful. You may now close this window.</h2>');
server.close();
createMainWindow(userName);
} catch (error) {
res.status(500).send('Error fetching user info.');
server.close();
}
});
server.listen(3000, async () => {
const authUrl = `${AUTH_BASE_URL}/authz-srv/authz` +
`?client_id=${CLIENT_ID}` +
`&response_type=token` +
`&scope=${encodeURIComponent(SCOPE)}` +
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`;
await open(authUrl);
});
}
app.whenReady().then(() => {
startSSOFlow();
});
2. preload.js (Exposes IPC)
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
onUserWelcome: (callback) => ipcRenderer.on('user-welcome', (event, name) => callback(name))
});
3. index.html (Renderer process UI)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Skillmine Auth SSO</title>
</head>
<body>
<h1 id="welcome">Authenticating...</h1>
<script>
window.electronAPI.onUserWelcome((name) => {
document.getElementById('welcome').textContent = `👋 Welcome ${name}`;
});
</script>
</body>
</html>
Step 3 : Execution
npx electron .
✅ Summary Flow
Electron App Start → Check Session → Open Browser Login → Skillmine Auth → Redirect with Token → Fetch User Info → Show Welcome Message
Last updated