API Reference - React
Complete API documentation for @alien_org/sso-sdk-react.
AlienSsoProvider
Context provider component that wraps your application and provides authentication state.
Props
interface AlienSsoProviderProps {
config: AlienSsoClientConfig;
children: React.ReactNode;
}Configuration:
config.ssoBaseUrl(string, required): Base URL of the SSO serviceconfig.providerAddress(string, required): Your provider addressconfig.pollingInterval(number, optional): Polling interval in milliseconds (default: 5000)
Example:
import { AlienSsoProvider } from '@alien_org/sso-sdk-react';
function App() {
return (
<AlienSsoProvider
config={{
ssoBaseUrl: 'https://sso.alien-api.com',
providerAddress: 'your-provider-address',
pollingInterval: 5000
}}
>
<YourApp />
</AlienSsoProvider>
);
}useAuth Hook
Hook that provides access to authentication state and methods. Must be used within AlienSsoProvider.
function useAuth(): UseAuthReturnReturn Value
interface UseAuthReturn {
client: AlienSsoClient;
auth: AuthState;
queryClient: QueryClient;
generateDeeplink: () => Promise<AuthorizeResponse>;
pollAuth: (pollingCode: string) => Promise<PollResponse>;
exchangeToken: (authCode: string) => Promise<string>;
verifyAuth: () => Promise<boolean>;
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;
}
interface TokenInfo {
app_callback_session_address: string;
issued_at: number;
expired_at: number;
}Example:
const { auth } = useAuth();
if (auth.isAuthenticated) {
console.log('Session:', auth.tokenInfo?.app_callback_session_address);
console.log('Token:', auth.token);
}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;
polling_code: string;
expired_at: number;
}Example:
const { generateDeeplink } = useAuth();
const handleSignIn = async () => {
const { deep_link, polling_code } = await generateDeeplink();
console.log('Deep link:', deep_link);
};pollAuth()
Polls for authentication status.
async pollAuth(pollingCode: string): Promise<PollResponse>Parameters:
pollingCode(string): Polling code fromgenerateDeeplink()
Returns:
{
status: 'pending' | 'authorized' | 'rejected' | 'expired';
authorization_code?: string;
}Example:
const { pollAuth } = useAuth();
const response = await pollAuth(polling_code);
if (response.status === 'authorized') {
console.log('Auth code:', response.authorization_code);
}exchangeToken()
Exchanges authorization code for access token.
async exchangeToken(authCode: string): Promise<string>Parameters:
authCode(string): Authorization code frompollAuth()
Returns: Promise<string> - Access token
Side Effects:
- Updates
authstate - Stores token in localStorage
Example:
const { exchangeToken } = useAuth();
const token = await exchangeToken(authorization_code);
console.log('Token:', token);verifyAuth()
Verifies current access token with server.
async verifyAuth(): Promise<boolean>Returns: Promise<boolean> - true if valid, false otherwise
Example:
const { verifyAuth } = useAuth();
const isValid = await verifyAuth();
if (!isValid) {
console.log('Token expired or invalid');
}logout()
Clears authentication state and storage.
logout(): voidSide Effects:
- Updates
authstate to unauthenticated - Removes token from localStorage
- Removes code verifier from sessionStorage
Example:
const { logout } = useAuth();
<button onClick={logout}>Logout</button>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}>Close</button>}isModalOpen
Boolean indicating if the sign-in modal is currently open.
const { isModalOpen } = useAuth();
console.log('Modal open:', isModalOpen);Components
SignInButton
Pre-styled button component that opens the sign-in modal.
function SignInButton(): JSX.ElementExample:
import { SignInButton } from '@alien_org/sso-sdk-react';
function LoginPage() {
return (
<div>
<h1>Welcome</h1>
<SignInButton />
</div>
);
}Styling:
The button has default styles but can be customized via CSS:
/* Target the button */
button.alien-sso-signin-button {
/* Your custom styles */
}SignInModal
Modal component for the authentication flow. Automatically rendered by AlienSsoProvider.
This component:
- Displays QR code with deep link
- Handles polling automatically
- Shows loading and error states
- Exchanges token on successful authentication
Controlling the modal:
const { openModal, closeModal } = useAuth();
// Open modal
openModal();
// Close modal
closeModal();Types
AlienSsoClientConfig
interface AlienSsoClientConfig {
ssoBaseUrl: string;
providerAddress: string;
pollingInterval?: number;
}AuthState
interface AuthState {
isAuthenticated: boolean;
token: string | null;
tokenInfo: TokenInfo | null;
}TokenInfo
interface TokenInfo {
app_callback_session_address: string;
issued_at: number;
expired_at: number;
}AuthorizeResponse
interface AuthorizeResponse {
deep_link: string;
polling_code: string;
expired_at: number;
}PollResponse
interface PollResponse {
status: 'pending' | 'authorized' | 'rejected' | 'expired';
authorization_code?: string;
}Usage Examples
Basic Authentication
import { AlienSsoProvider, useAuth, SignInButton } from '@alien_org/sso-sdk-react';
function App() {
return (
<AlienSsoProvider
config={{
ssoBaseUrl: 'https://sso.alien-api.com',
providerAddress: 'your-provider-address',
}}
>
<Dashboard />
</AlienSsoProvider>
);
}
function Dashboard() {
const { auth, logout } = useAuth();
if (!auth.isAuthenticated) {
return <SignInButton />;
}
return (
<div>
<p>Welcome! Session: {auth.tokenInfo?.app_callback_session_address}</p>
<button onClick={logout}>Logout</button>
</div>
);
}Protected Route
import { useAuth } from '@alien_org/sso-sdk-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}</>;
}
// Usage
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>Custom Sign-In Flow
import { useAuth } from '@alien_org/sso-sdk-react';
import { useState, useEffect } from 'react';
function CustomSignIn() {
const { generateDeeplink, pollAuth, exchangeToken } = 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, pollAuth, exchangeToken]);
if (deepLink) {
return <QRCode value={deepLink} />;
}
return <button onClick={handleSignIn}>Sign In</button>;
}Token Verification on Mount
import { useAuth } from '@alien_org/sso-sdk-react';
import { useEffect } from 'react';
function App() {
const { verifyAuth, auth } = useAuth();
useEffect(() => {
// Verify token on app mount
if (auth.token) {
verifyAuth();
}
}, []);
// Rest of your app
}Checking Token Expiry
import { useAuth } from '@alien_org/sso-sdk-react';
import { useEffect } from 'react';
function App() {
const { auth, logout } = useAuth();
useEffect(() => {
if (!auth.tokenInfo) return;
const checkExpiry = () => {
if (auth.tokenInfo.expired_at * 1000 < Date.now()) {
logout();
alert('Session expired, please sign in again');
}
};
// Check every minute
const interval = setInterval(checkExpiry, 60000);
return () => clearInterval(interval);
}, [auth.tokenInfo, logout]);
// Rest of your app
}Error Handling
All async methods can throw errors. Handle them appropriately:
const { generateDeeplink, exchangeToken } = useAuth();
try {
const { deep_link, polling_code } = await generateDeeplink();
} catch (error) {
console.error('Failed to generate deep link:', error);
// Show error to user
}
try {
await exchangeToken(authCode);
} catch (error) {
console.error('Token exchange failed:', error);
// Show error to user
}Next Steps
- Core API Reference - Core SDK documentation
- React Integration Guide - Integration guide
- Demo App - See complete implementation