JAVASCRIPT
Client-Side OAuth 2.0 Authorization Code Flow
Implement client-side OAuth 2.0 Authorization Code Grant: redirect for consent, then exchange the authorization code for an access token securely.
// Configuration
const CLIENT_ID = 'YOUR_CLIENT_ID';
const REDIRECT_URI = 'http://localhost:3000/callback'; // Must match your registered redirect URI
const AUTHORIZATION_URL = 'https://provider.com/oauth/authorize';
const TOKEN_URL = 'https://provider.com/oauth/token'; // Server-side or proxy for production!
const SCOPES = 'read:user write:posts'; // Space-separated scopes
// Step 1: Redirect user for authorization
function initiateOAuthFlow() {
const state = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); // Simple random state
localStorage.setItem('oauth_state', state);
const params = new URLSearchParams({
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
response_type: 'code',
scope: SCOPES,
state: state,
});
window.location.href = `${AUTHORIZATION_URL}?${params.toString()}`;
}
// Step 2: Handle callback and exchange code for token
async function handleOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const receivedState = urlParams.get('state');
const storedState = localStorage.getItem('oauth_state');
if (!code || !receivedState || receivedState !== storedState) {
console.error('OAuth state mismatch or missing code.');
return;
}
localStorage.removeItem('oauth_state'); // Clear state after validation
try {
// In a real application, this token exchange should happen on a secure backend server
// to prevent exposing client secret and for better security.
const response = await fetch(TOKEN_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code',
code: code,
// client_secret: 'YOUR_CLIENT_SECRET' // ONLY IF EXCHANGING ON SERVER-SIDE
}),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Token exchange failed: ${errorData.error_description || response.statusText}`);
}
const tokenData = await response.json();
console.log('Access Token:', tokenData.access_token);
console.log('Refresh Token (if any):', tokenData.refresh_token);
// Store tokens securely (e.g., HttpOnly cookies for web apps, localStorage with care)
// Then, redirect or update UI
} catch (error) {
console.error('Error during token exchange:', error);
}
}
// Example usage:
// Call initiateOAuthFlow() when a 'Login with Provider' button is clicked.
// Call handleOAuthCallback() on your /callback page load.
// Ensure your server handles the /callback route and renders necessary JS.
How it works: This snippet demonstrates the client-side portion of the OAuth 2.0 Authorization Code Grant flow. `initiateOAuthFlow` constructs the authorization URL and redirects the user to the OAuth provider for consent. Upon successful authorization, the user is redirected back to the `REDIRECT_URI` with an `authorization_code`. The `handleOAuthCallback` function then extracts this code and (ideally, via a secure backend proxy) exchanges it for an `access_token` and potentially a `refresh_token`. State parameter validation is included for security.