Alien SSO React API Reference: AlienSsoProvider and useAuth
Complete API documentation for @alien-id/sso-react.
AlienSsoProvider: Props and Configuration
Context provider component that wraps your application and provides authentication state.
Props
interface AlienSsoProviderProps {
config: AlienSsoClientConfig;
children: React.ReactNode;
}Configuration:
| Parameter | Type | Required | Description |
|---|---|---|---|
ssoBaseUrl | string | Yes | Base URL of the SSO service |
providerAddress | string | Yes | Your provider address |
pollingInterval | number | No | Polling interval in ms (default: 5000) |
agentId | object | No | Agent ID configuration (see below) |
agentId.enabled | boolean | No | Enable the Agent tab in the sign-in modal |
agentId.skillUrl | string | No | URL to your service’s ALIEN-SKILL.md (default: /ALIEN-SKILL.md) |
Example:
import { AlienSsoProvider } from "@alien-id/sso-react";
function App() {
return (
<AlienSsoProvider
config={{
ssoBaseUrl: "https://sso.alien.com",
providerAddress: "your-provider-address",
pollingInterval: 5000,
}}
>
<YourApp />
</AlienSsoProvider>
);
}useAuth Hook: Methods and Return Values
Hook that provides access to authentication state and methods. Must be used within AlienSsoProvider.
function useAuth(): UseAuthReturn;Return Value
interface UseAuthReturn {
client: AlienSsoClient;
auth: AuthState;
queryClient: QueryClient;
generateDeeplink: () => Promise<AuthorizeResponse>;
pollAuth: (pollingCode: string) => Promise<PollResponse>;
exchangeToken: (authCode: string) => Promise<TokenResponse>;
verifyAuth: () => Promise<boolean>;
refreshToken: () => Promise<string | null>;
logout: () => void;
openModal: () => void;
closeModal: () => void;
isModalOpen: boolean;
}Properties
client
Direct access to the AlienSsoClient instance.
const { client } = useAuth();
const token = client.getAccessToken();auth
Current authentication state.
interface AuthState {
isAuthenticated: boolean;
token: string | null;
tokenInfo: TokenInfo | null;
}TokenInfo (OIDC standard claims):
interface TokenInfo {
iss: string; // Issuer URL
sub: string; // Subject (user identifier)
aud: string | string[]; // Audience (provider address)
exp: number; // Expiration timestamp
iat: number; // Issued at timestamp
nonce?: string; // Nonce if provided
auth_time?: number; // Authentication time
}Example:
const { auth } = useAuth();
if (auth.isAuthenticated) {
console.log("User ID:", auth.tokenInfo?.sub);
console.log("Token:", auth.token);
console.log("Expires:", new Date(auth.tokenInfo!.exp * 1000));
}queryClient
React Query client instance for advanced usage.
const { queryClient } = useAuth();
queryClient.invalidateQueries(["some-key"]);Methods
generateDeeplink()
Generates authentication deep link and polling code.
async generateDeeplink(): Promise<AuthorizeResponse>Returns:
{
deep_link: string; // URL for QR code or redirect
polling_code: string; // Code for polling status
expired_at: number; // Unix timestamp
}pollAuth()
Polls for authentication status.
async pollAuth(pollingCode: string): Promise<PollResponse>Returns:
{
status: 'pending' | 'authorized' | 'rejected' | 'expired';
authorization_code?: string; // Only when status is 'authorized'
}exchangeToken()
Exchanges authorization code for tokens. Updates auth state on success.
async exchangeToken(authCode: string): Promise<TokenResponse>Returns:
{
access_token: string;
id_token: string;
refresh_token: string;
token_type: string;
expires_in: number;
}Side Effects:
- Updates
authstate with new tokens - Stores tokens in localStorage
verifyAuth()
Verifies current access token by calling /oauth/userinfo.
async verifyAuth(): Promise<boolean>Returns: true if token is valid, false otherwise.
Side Effects:
- Updates
authstate based on verification result - Automatically refreshes token on 401 (via underlying client)
refreshToken()
Refreshes the access token using the stored refresh token.
async refreshToken(): Promise<string | null>Returns: the refreshed access token on success, or null if refresh failed.
Side Effects:
- Updates
authstate with new tokens on success - Clears auth state and calls logout on failure
Example:
const { refreshToken, auth } = useAuth();
// Proactive refresh before token expires
if (auth.tokenInfo && auth.tokenInfo.exp * 1000 < Date.now() + 60000) {
const accessToken = await refreshToken();
if (!accessToken) {
// Redirect to login
}
}logout()
Clears authentication state and storage.
logout(): voidSide Effects:
- Updates
authstate to unauthenticated - Removes all tokens from localStorage
- Removes code verifier from sessionStorage
openModal() / closeModal()
Control the built-in sign-in modal.
openModal(): void
closeModal(): voidExample:
const { openModal, closeModal, isModalOpen } = useAuth();
<button onClick={openModal}>Sign In</button>;
{
isModalOpen && <button onClick={closeModal}>Cancel</button>;
}isModalOpen
Boolean indicating if the sign-in modal is currently open.
Components
SignInButton
Pre-styled button component that opens the sign-in modal.
function SignInButton(): JSX.Element;Example:
import { SignInButton } from "@alien-id/sso-react";
function LoginPage() {
return (
<div>
<h1>Welcome</h1>
<SignInButton />
</div>
);
}SignInModal
Modal component for the authentication flow. Automatically rendered by AlienSsoProvider.
This component:
- Displays QR code with deep link for human authentication
- Handles polling automatically
- Shows loading and error states
- Exchanges token on successful authentication
- Updates auth state when complete
- When
agentId.enabledistrue, shows a Human/Agent tab switcher with a sliding indicator - The Agent tab displays the skill install command with a copy button and setup instructions
Controlling the modal:
const { openModal, closeModal } = useAuth();
openModal(); // Open modal
closeModal(); // Close modalTypeScript Types Reference
AlienSsoClientConfig
interface AlienSsoClientConfig {
ssoBaseUrl: string;
providerAddress: string;
pollingInterval?: number;
agentId?: {
enabled: boolean;
skillUrl?: string;
};
}AuthState
interface AuthState {
isAuthenticated: boolean;
token: string | null;
tokenInfo: TokenInfo | null;
}TokenInfo
interface TokenInfo {
iss: string;
sub: string;
aud: string | string[];
exp: number;
iat: number;
nonce?: string;
auth_time?: number;
}AuthorizeResponse
interface AuthorizeResponse {
deep_link: string;
polling_code: string;
expired_at: number;
}PollResponse
interface PollResponse {
status: "pending" | "authorized" | "rejected" | "expired";
authorization_code?: string;
}TokenResponse
interface TokenResponse {
access_token: string;
id_token: string;
refresh_token: string;
token_type: string;
expires_in: number;
}Usage Examples
Basic Authentication
import { AlienSsoProvider, useAuth, SignInButton } from "@alien-id/sso-react";
function App() {
return (
<AlienSsoProvider
config={{
ssoBaseUrl: "https://sso.alien.com",
providerAddress: "your-provider-address",
}}
>
<Dashboard />
</AlienSsoProvider>
);
}
function Dashboard() {
const { auth, logout } = useAuth();
if (!auth.isAuthenticated) {
return <SignInButton />;
}
return (
<div>
<p>Welcome! User ID: {auth.tokenInfo?.sub}</p>
<button onClick={logout}>Logout</button>
</div>
);
}Protected Route
import { useAuth } from "@alien-id/sso-react";
import { Navigate } from "react-router-dom";
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { auth } = useAuth();
if (!auth.isAuthenticated) {
return <Navigate to="/login" replace />;
}
return <>{children}</>;
}Token Refresh on API Calls
import { useAuth } from "@alien-id/sso-react";
function useApi() {
const { auth, refreshToken, logout } = useAuth();
async function fetchWithAuth(url: string) {
// Check if token is expiring within 1 minute
if (auth.tokenInfo && auth.tokenInfo.exp * 1000 < Date.now() + 60000) {
const accessToken = await refreshToken();
if (!accessToken) {
logout();
throw new Error("Session expired");
}
}
return fetch(url, {
headers: {
Authorization: `Bearer ${auth.token}`,
},
});
}
return { fetchWithAuth };
}Custom Sign-In Flow
import { useAuth } from "@alien-id/sso-react";
import { useState, useEffect } from "react";
function CustomSignIn() {
const { generateDeeplink, pollAuth, exchangeToken, auth } = useAuth();
const [deepLink, setDeepLink] = useState<string | null>(null);
const [pollingCode, setPollingCode] = useState<string | null>(null);
const handleSignIn = async () => {
const response = await generateDeeplink();
setDeepLink(response.deep_link);
setPollingCode(response.polling_code);
};
useEffect(() => {
if (!pollingCode) return;
const interval = setInterval(async () => {
const response = await pollAuth(pollingCode);
if (response.status === "authorized") {
clearInterval(interval);
await exchangeToken(response.authorization_code!);
setDeepLink(null);
setPollingCode(null);
} else if (
response.status === "rejected" ||
response.status === "expired"
) {
clearInterval(interval);
setDeepLink(null);
setPollingCode(null);
}
}, 5000);
return () => clearInterval(interval);
}, [pollingCode]);
if (deepLink) {
return <QRCode value={deepLink} />;
}
return <button onClick={handleSignIn}>Sign In</button>;
}Token Verification on Mount
import { useAuth } from "@alien-id/sso-react";
import { useEffect } from "react";
function App() {
const { verifyAuth, auth } = useAuth();
useEffect(() => {
if (auth.token) {
verifyAuth();
}
}, []);
// Rest of your app
}Agent Mode
When agentId.enabled is set in the config, the sign-in modal shows a Human/Agent tab switcher. The Agent tab guides users to install the Agent ID skill and authenticate their AI agent.
<AlienSsoProvider
config={{
ssoBaseUrl: "https://sso.alien-api.com",
providerAddress: "your-provider-address",
agentId: {
enabled: true,
skillUrl: "/ALIEN-SKILL.md", // optional, this is the default
},
}}
>
<App />
</AlienSsoProvider>The Agent tab displays:
- An install command (
npx skills add alien-id/agent-id) with a copy button - Steps: install Agent ID, paste the service URL to the agent, authenticate
On the server side, verify agent tokens using @alien-id/sso-agent-id. See the Service Integration Guide for verification setup and ALIEN-SKILL.md hosting.
For a working example, see the Agent ID Demo App.
Error Handling
All async methods can throw errors. Handle them appropriately:
const { generateDeeplink, exchangeToken, refreshToken } = useAuth();
try {
const { deep_link, polling_code } = await generateDeeplink();
} catch (error) {
console.error("Failed to generate deep link:", error);
}
try {
await exchangeToken(authCode);
} catch (error) {
console.error("Token exchange failed:", error);
}
try {
const accessToken = await refreshToken();
if (!accessToken) {
// Handle refresh failure (user logged out automatically)
}
} catch (error) {
console.error("Refresh error:", error);
}Next Steps
- Core API Reference - Core SDK documentation
- React Integration Guide - Integration guide
- Service Integration - Add Agent ID verification to your backend
- Demo App - Agent guestbook example