Skip to Content
⚠️ Note: Some details in this documentation may not be fully accurate yet.
GuideCore Integration

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
  • localStorage and sessionStorage support
  • A registered provider from the developer portal with provider address

Installation

npm install @alien_org/sso-sdk-core

Setup

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

OptionTypeRequiredDescription
ssoBaseUrlstringYesBase URL of the SSO service
providerAddressstringYesYour provider address from developer portal
pollingIntervalnumberNoPolling interval in ms (default: 5000)

Authentication Flow

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/token with grant_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/userinfo with Bearer token
  • Automatically refreshes token on 401 error
  • Returns user info or null if 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 token

Refresh 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:

  1. Execute your function
  2. If it fails with 401, automatically refresh the token
  3. Retry your function with the new token
  4. 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 sessionStorage

Complete 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

KeyDescription
alien-sso_access_tokenJWT access token
alien-sso_id_tokenJWT ID token
alien-sso_refresh_tokenRefresh token
alien-sso_token_expiryToken expiry timestamp

sessionStorage

KeyDescription
alien-sso_code_verifierPKCE 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

Last updated on