JAVASCRIPT
Initiate OAuth 2.0 Authorization Code Flow from Client
Guide users through the first step of OAuth 2.0 Authorization Code Flow, initiating the redirect to the authorization server to request user consent and an authorization code.
/**
* Initiates the OAuth 2.0 Authorization Code Flow by redirecting the user
* to the authorization server's login/consent page.
* This is the first step in obtaining an access token.
* @param {string} authorizationUrl - The base URL of the OAuth authorization endpoint.
* @param {string} clientId - Your application's client ID.
* @param {string} redirectUri - The URL where the authorization server will redirect back to.
* @param {string} scope - A space-separated list of scopes (permissions) your app needs.
* @param {string} state - An opaque value used to maintain state between the request and callback.
* Protects against CSRF attacks.
* @param {string} [codeChallenge] - PKCE code challenge (optional, but recommended for public clients).
* @param {string} [codeChallengeMethod='S256'] - PKCE code challenge method (e.g., 'S256').
*/
function initiateOAuthFlow(
authorizationUrl,
clientId,
redirectUri,
scope,
state,
codeChallenge = null,
codeChallengeMethod = 'S256'
) {
const params = new URLSearchParams({
response_type: 'code',
client_id: clientId,
redirect_uri: redirectUri,
scope: scope,
state: state,
});
if (codeChallenge) {
params.append('code_challenge', codeChallenge);
params.append('code_challenge_method', codeChallengeMethod);
}
const fullAuthUrl = `${authorizationUrl}?${params.toString()}`;
console.log("Redirecting to:", fullAuthUrl);
window.location.href = fullAuthUrl; // Redirect the user
}
// --- Usage Example ---
// In a real application, these values would come from configuration/environment
const AUTH_SERVER_URL = 'https://accounts.example.com/oauth/authorize';
const CLIENT_ID = 'your_client_id_123';
const REDIRECT_URI = 'http://localhost:3000/callback'; // Must be registered with auth server
const SCOPES = 'read:profile write:data';
const CSRF_STATE = 'random_string_to_prevent_csrf'; // Generate a strong random string
// For PKCE (Proof Key for Code Exchange) - highly recommended for public clients
// In a real app, generate `code_verifier` and `code_challenge` dynamically.
// Store `code_verifier` securely (e.g., in localStorage) to use in the token exchange.
async function generatePkceChallenge() {
const verifier = Array.from(crypto.getRandomValues(new Uint8Array(32)))
.map(b => b.toString(16).padStart(2, '0')).join(''); // Simple hex string, better to use base64url
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const digest = await crypto.subtle.digest('SHA-256', data);
const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+\s*$/, ''); // base64url encode
return { verifier, challenge };
}
// To initiate without PKCE (less secure for public clients):
// initiateOAuthFlow(AUTH_SERVER_URL, CLIENT_ID, REDIRECT_URI, SCOPES, CSRF_STATE);
// To initiate with PKCE (recommended):
async function startLogin() {
const { verifier, challenge } = await generatePkceChallenge();
localStorage.setItem('oauth_code_verifier', verifier); // Store verifier for token exchange
localStorage.setItem('oauth_state', CSRF_STATE); // Store state to verify on callback
initiateOAuthFlow(
AUTH_SERVER_URL,
CLIENT_ID,
REDIRECT_URI,
SCOPES,
CSRF_STATE,
challenge,
'S256'
);
}
// Call this function when a "Login with OAuth" button is clicked
// startLogin(); // Uncomment to test (will redirect)
How it works: This JavaScript snippet outlines the client-side initiation of the OAuth 2.0 Authorization Code Flow, specifically for public clients using PKCE (Proof Key for Code Exchange). It constructs the authorization URL with necessary parameters like `client_id`, `redirect_uri`, `scope`, and a `state` parameter for CSRF protection. The function then redirects the user to the authorization server, prompting them to grant permissions. Upon successful authorization, the server redirects back to your `redirect_uri` with an authorization `code` and the `state` parameter, which are then used by your backend (or a secure client-side setup with PKCE) to exchange for an access token.