JavaScript/TypeScript SDK
Official OAuth42 SDK for JavaScript and TypeScript. Works in Node.js, browsers, and modern frameworks.
Installation
Install the OAuth42 SDK using npm, yarn, or pnpm:
npm install @oauth42/clientyarn add @oauth42/clientpnpm add @oauth42/clientTypeScript Support
The SDK is written in TypeScript and includes full type definitions. No additional @types packages needed.
Quick Start
1. Initialize the Client
import { OAuth42Client } from '@oauth42/client';
const client = new OAuth42Client({
clientId: 'your_client_id',
clientSecret: 'your_client_secret', // Optional, for server-side only
redirectUri: 'https://yourapp.com/callback',
issuer: 'https://oauth42.com', // Optional, defaults to oauth42.com
});2. Start Authorization Flow
// Generate authorization URL with PKCE
const { url, codeVerifier, state } = await client.authorize({
scope: ['openid', 'profile', 'email'],
responseType: 'code',
});
// Store codeVerifier and state in session
sessionStorage.setItem('code_verifier', codeVerifier);
sessionStorage.setItem('state', state);
// Redirect user to authorization URL
window.location.href = url;3. Handle Callback
// Parse callback URL
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
// Verify state
const storedState = sessionStorage.getItem('state');
if (state !== storedState) {
throw new Error('Invalid state parameter');
}
// Exchange code for tokens
const codeVerifier = sessionStorage.getItem('code_verifier');
const tokens = await client.exchangeCodeForTokens({
code,
codeVerifier,
});
// tokens.accessToken, tokens.refreshToken, tokens.idToken
console.log('Access token:', tokens.accessToken);Configuration
The OAuth42Client constructor accepts the following options:
clientIdrequiredYour application's client ID from the OAuth42 dashboard.
redirectUrirequiredThe redirect URI registered in your OAuth42 application settings.
clientSecretoptionalYour application's client secret. Only use on server-side! Never expose in browser code.
issueroptionalThe OAuth42 issuer URL. Defaults to https://oauth42.com
scopeoptionalDefault scopes to request. Can be overridden per authorization.
pkceoptionalEnable PKCE (default: true). Strongly recommended for all clients.
Authentication Flows
Authorization Code Flow with PKCE (Recommended)
Recommended for Single-Page Applications (React, Vue, Angular) and mobile apps.
// Start authorization
const { url, codeVerifier, state } = await client.authorize({
scope: ['openid', 'profile', 'email'],
responseType: 'code',
state: 'random_state_value', // Optional, auto-generated if not provided
});
// Store for later
sessionStorage.setItem('code_verifier', codeVerifier);
sessionStorage.setItem('state', state);
// Redirect user
window.location.href = url;
// --- After redirect callback ---
// Exchange code for tokens
const tokens = await client.exchangeCodeForTokens({
code: params.get('code'),
codeVerifier: sessionStorage.getItem('code_verifier'),
});Client Credentials Flow
For server-to-server communication. Requires client secret.
// Server-side only
const client = new OAuth42Client({
clientId: process.env.OAUTH42_CLIENT_ID,
clientSecret: process.env.OAUTH42_CLIENT_SECRET,
});
const tokens = await client.clientCredentials({
scope: ['api:read', 'api:write'],
});
// Use access token for API calls
console.log(tokens.accessToken);Refresh Token Flow
// Refresh expired access token
const newTokens = await client.refreshTokens({
refreshToken: storedRefreshToken,
});
// Store new tokens
console.log('New access token:', newTokens.accessToken);
console.log('New refresh token:', newTokens.refreshToken);User Management
Get User Info
const userInfo = await client.getUserInfo(accessToken);
console.log('User ID:', userInfo.sub);
console.log('Name:', userInfo.name);
console.log('Email:', userInfo.email);
console.log('Email verified:', userInfo.email_verified);Update User Profile
await client.updateUser(accessToken, {
name: 'John Doe',
picture: 'https://example.com/avatar.jpg',
});Change Password
await client.changePassword(accessToken, {
currentPassword: 'old_password',
newPassword: 'new_secure_password',
});Token Management
Validate Token
const isValid = await client.validateToken(accessToken);
if (isValid) {
console.log('Token is valid');
} else {
console.log('Token is expired or invalid');
}Introspect Token
const tokenInfo = await client.introspectToken(accessToken);
console.log('Active:', tokenInfo.active);
console.log('Expires at:', tokenInfo.exp);
console.log('Scopes:', tokenInfo.scope);
console.log('Client ID:', tokenInfo.client_id);Revoke Token
// Revoke access token or refresh token
await client.revokeToken(token);
console.log('Token revoked successfully');Multi-Factor Authentication
Setup MFA
const mfaSetup = await client.setupMFA(accessToken);
console.log('Secret:', mfaSetup.secret);
console.log('QR Code:', mfaSetup.qrCode); // Data URL for QR code
console.log('Backup codes:', mfaSetup.backupCodes);
// User scans QR code with authenticator app
// Then verify with first code
await client.verifyMFASetup(accessToken, {
code: '123456', // From authenticator app
});Verify MFA Code
// During login, after receiving MFA challenge
const tokens = await client.verifyMFA({
mfaToken: mfaToken, // From authorization response
code: '123456', // From authenticator app
});
console.log('Access token:', tokens.accessToken);Disable MFA
await client.disableMFA(accessToken, {
password: 'user_password', // Required for security
});Error Handling
The SDK throws typed errors that you can catch and handle appropriately:
import { OAuth42Client, OAuth42Error } from '@oauth42/client';
try {
const tokens = await client.exchangeCodeForTokens({
code: authCode,
codeVerifier: verifier,
});
} catch (error) {
if (error instanceof OAuth42Error) {
console.error('OAuth42 Error:', error.message);
console.error('Error code:', error.code);
console.error('Status:', error.status);
switch (error.code) {
case 'invalid_grant':
// Authorization code expired or invalid
console.error('Authorization code is invalid');
break;
case 'invalid_client':
// Client credentials are wrong
console.error('Client authentication failed');
break;
case 'access_denied':
// User denied authorization
console.error('User denied access');
break;
default:
console.error('Unknown error:', error.code);
}
} else {
// Network or other error
console.error('Unexpected error:', error);
}
}Common Error Codes
invalid_grantAuthorization code or refresh token is invalid or expired
invalid_clientClient authentication failed (wrong credentials)
invalid_requestRequest is missing required parameters or malformed
unauthorized_clientClient is not authorized for this grant type
access_deniedUser denied the authorization request
invalid_scopeRequested scope is invalid or not allowed
Framework Integration
React
import { useState, useEffect } from 'react';
import { OAuth42Client } from '@oauth42/client';
const client = new OAuth42Client({
clientId: import.meta.env.VITE_OAUTH42_CLIENT_ID,
redirectUri: `${window.location.origin}/callback`,
});
export function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const token = localStorage.getItem('access_token');
if (token) {
client.getUserInfo(token)
.then(setUser)
.catch(() => localStorage.removeItem('access_token'))
.finally(() => setLoading(false));
} else {
setLoading(false);
}
}, []);
const login = async () => {
const { url, codeVerifier, state } = await client.authorize({
scope: ['openid', 'profile', 'email'],
});
sessionStorage.setItem('code_verifier', codeVerifier);
sessionStorage.setItem('state', state);
window.location.href = url;
};
const logout = () => {
localStorage.removeItem('access_token');
setUser(null);
};
return { user, loading, login, logout };
}
// Usage in component
function App() {
const { user, loading, login, logout } = useAuth();
if (loading) return <div>Loading...</div>;
return (
<div>
{user ? (
<>
<p>Welcome, {user.name}!</p>
<button onClick={logout}>Logout</button>
</>
) : (
<button onClick={login}>Login</button>
)}
</div>
);
}Express.js
import express from 'express';
import session from 'express-session';
import { OAuth42Client } from '@oauth42/client';
const app = express();
const client = new OAuth42Client({
clientId: process.env.OAUTH42_CLIENT_ID,
clientSecret: process.env.OAUTH42_CLIENT_SECRET,
redirectUri: 'http://localhost:3000/callback',
});
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
}));
app.get('/login', async (req, res) => {
const { url, codeVerifier, state } = await client.authorize({
scope: ['openid', 'profile', 'email'],
});
req.session.codeVerifier = codeVerifier;
req.session.state = state;
res.redirect(url);
});
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
if (state !== req.session.state) {
return res.status(400).send('Invalid state');
}
const tokens = await client.exchangeCodeForTokens({
code,
codeVerifier: req.session.codeVerifier,
});
req.session.accessToken = tokens.accessToken;
req.session.refreshToken = tokens.refreshToken;
res.redirect('/dashboard');
});
app.get('/dashboard', async (req, res) => {
if (!req.session.accessToken) {
return res.redirect('/login');
}
const user = await client.getUserInfo(req.session.accessToken);
res.json({ user });
});
app.listen(3000);Best Practices
Always Use PKCE
PKCE is enabled by default and should always be used for SPAs and mobile apps to prevent authorization code interception attacks.
Never Expose Client Secret
Client secrets should only be used server-side. Never include them in browser JavaScript or mobile app code.
Implement Token Refresh
Automatically refresh access tokens before they expire to provide seamless user experience without re-authentication.
Validate State Parameter
Always verify the state parameter matches what you sent to prevent CSRF attacks during authorization.
Use Secure Storage
Store tokens securely. Use httpOnly cookies for server-side or secure session storage for client-side. Avoid localStorage for sensitive tokens.
Handle Errors Gracefully
Catch and handle OAuth42Error instances to provide meaningful error messages to users and implement appropriate retry logic.
Next Steps
Build Your First App
Follow our step-by-step tutorial to build a complete application with OAuth42 authentication.
API Reference
Explore the complete OAuth42 API documentation with detailed endpoint specifications.
Multi-Factor Authentication
Learn how to implement TOTP-based MFA to enhance security in your application.
Security Best Practices
Comprehensive guide to securing your OAuth 2.0 implementation.