Core Integration Guide
This guide shows how to integrate Alien SSO into any JavaScript/TypeScript project using the core SDK.
Requirements
- A modern web browser with JavaScript enabled
localStorageandsessionStoragesupport- A registered provider from the developer portal with provider address
Installation
npm install @alien_org/sso-sdk-coreSetup
Initialize the Client
import { AlienSsoClient } from '@alien_org/sso-sdk-core';
const client = new AlienSsoClient({
ssoBaseUrl: 'https://sso.alien-api.com',
providerAddress: 'your-provider-address'
});Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
ssoBaseUrl | string | Yes | Base URL of the SSO service |
providerAddress | string | Yes | Your provider address from developer portal |
pollingInterval | number | No | Polling interval in ms (default: 5000) |
Authentication Flow
Step 1: Generate Deep Link
const { deep_link, polling_code, expired_at } = await client.generateDeeplink();
// Display QR code with deep_link
displayQRCode(deep_link);
// Or redirect mobile users
window.location.href = deep_link;The generateDeeplink() method:
- Sends
GET /oauth/authorize?response_type=code&response_mode=json&... - Generates PKCE code verifier/challenge (S256)
- Stores code verifier in
sessionStorage - Returns deep link for user authentication
Step 2: Poll for Authorization
const pollInterval = setInterval(async () => {
const response = await client.pollAuth(polling_code);
if (response.status === 'authorized') {
clearInterval(pollInterval);
// Proceed to token exchange
const tokens = await client.exchangeToken(response.authorization_code);
console.log('Authenticated!', tokens);
} else if (response.status === 'rejected') {
clearInterval(pollInterval);
console.error('User denied authentication');
} else if (response.status === 'expired') {
clearInterval(pollInterval);
console.error('Session expired');
}
// If status is 'pending', continue polling
}, 5000);Step 3: Exchange Code for Tokens
const tokens = await client.exchangeToken(authorizationCode);
// Returns: { access_token, id_token, refresh_token, token_type, expires_in }The exchangeToken() method:
- Sends
POST /oauth/tokenwithgrant_type=authorization_code - Retrieves code verifier from
sessionStorage - Stores all tokens in
localStorage - Returns the full token response
Step 4: Get User Info
const userInfo = await client.verifyAuth();
if (userInfo) {
console.log('User ID:', userInfo.sub);
}The verifyAuth() method:
- Sends
GET /oauth/userinfowith Bearer token - Automatically refreshes token on 401 error
- Returns user info or
nullif not authenticated
Token Management
Get Stored Tokens
// Access token (for API calls)
const accessToken = client.getAccessToken();
// ID token (contains user claims)
const idToken = client.getIdToken();
// Refresh token (for getting new access tokens)
const refreshToken = client.getRefreshToken();Get Token Claims
const claims = client.getAuthData();
if (claims) {
console.log('Subject (user ID):', claims.sub);
console.log('Issuer:', claims.iss);
console.log('Audience:', claims.aud);
console.log('Expires at:', new Date(claims.exp * 1000));
console.log('Issued at:', new Date(claims.iat * 1000));
}Check Token Expiry
// Check if token is expired
if (client.isTokenExpired()) {
console.log('Token expired');
}
// Check if token will expire soon (within 5 minutes)
if (client.isAccessTokenExpired()) {
console.log('Token expiring soon, should refresh');
}Get User Subject
const userId = client.getSubject();
// Returns the 'sub' claim from the tokenRefresh Tokens
Access tokens expire after a configured time (default: 30 minutes). Use refresh tokens to get new access tokens without re-authentication.
Manual Refresh
try {
const newTokens = await client.refreshAccessToken();
console.log('New access token:', newTokens.access_token);
} catch (error) {
// Refresh failed - user needs to re-authenticate
client.logout();
}Automatic Refresh
The SDK provides a helper for automatic token refresh:
// Wrap any authenticated request with auto-refresh
const result = await client.withAutoRefresh(async () => {
return await fetchProtectedResource();
});This will:
- Execute your function
- If it fails with 401, automatically refresh the token
- Retry your function with the new token
- If refresh fails, throw the original error
Example: API Calls with Auto-Refresh
async function fetchUserData() {
return await client.withAutoRefresh(async () => {
const response = await fetch('/api/user', {
headers: {
Authorization: `Bearer ${client.getAccessToken()}`
}
});
if (response.status === 401) {
const error = new Error('Unauthorized');
error.response = { status: 401 };
throw error;
}
return response.json();
});
}Logout
client.logout();
// Clears all tokens from localStorage and sessionStorageComplete Example
import { AlienSsoClient } from '@alien_org/sso-sdk-core';
const client = new AlienSsoClient({
ssoBaseUrl: 'https://sso.alien-api.com',
providerAddress: 'your-provider-address',
});
async function authenticate() {
try {
// Check if already authenticated
const userInfo = await client.verifyAuth();
if (userInfo) {
console.log('Already authenticated:', userInfo.sub);
return;
}
// Generate deep link
const { deep_link, polling_code } = await client.generateDeeplink();
// Display QR code
displayQRCode(deep_link);
// Poll for authorization
const pollInterval = setInterval(async () => {
const response = await client.pollAuth(polling_code);
if (response.status === 'authorized') {
clearInterval(pollInterval);
// Exchange code for tokens
const tokens = await client.exchangeToken(response.authorization_code);
console.log('Got tokens:', tokens);
// Get user info
const userInfo = await client.verifyAuth();
console.log('User:', userInfo?.sub);
hideQRCode();
} else if (response.status === 'rejected' || response.status === 'expired') {
clearInterval(pollInterval);
console.error('Authentication failed:', response.status);
hideQRCode();
}
}, 5000);
} catch (error) {
console.error('Authentication error:', error);
}
}Storage Keys
The SDK uses the following browser storage keys:
localStorage
| Key | Description |
|---|---|
alien-sso_access_token | JWT access token |
alien-sso_id_token | JWT ID token |
alien-sso_refresh_token | Refresh token |
alien-sso_token_expiry | Token expiry timestamp |
sessionStorage
| Key | Description |
|---|---|
alien-sso_code_verifier | PKCE code verifier (cleared after exchange) |
Error Handling
try {
const { deep_link, polling_code } = await client.generateDeeplink();
} catch (error) {
// Network error, server error, or invalid provider
console.error('Failed to generate deep link:', error.message);
}
try {
const tokens = await client.exchangeToken(authorizationCode);
} catch (error) {
// Invalid code, expired code, or missing code_verifier
console.error('Token exchange failed:', error.message);
}
try {
await client.refreshAccessToken();
} catch (error) {
// Refresh token expired or revoked
console.error('Refresh failed:', error.message);
client.logout(); // Force re-authentication
}Next Steps
- API Reference - Core - Complete API documentation
- React Integration Guide - For React applications
- Demo App - Example implementation
Last updated on