# Authorization Code Grant with PKCE Example PKCE (Proof Key for Code Exchange) is an OAuth 2.0 extension that secures public clients, such as mobile apps and single-page applications (SPAs) that cannot securely store a client secret. It helps prevent authorization code injection and CSRF attacks by using a one-time-use verifier. ### Overview * Firstup’s authorization server supports PKCE. * Only S256 (SHA-256 hashed) code challenges are accepted. * No client secret is needed. * Ideal for browser-based and mobile apps. ### Best Practices * Always use `S256` for the `code_challenge_method`. * Store code_verifier and state securely (e.g., local/session storage). * Use HTTPS for all endpoints. * Always validate the `state` parameter. * Do not reuse code_verifiers. ## Step 1: Generate Generate `code_verifier` and `code_challenge`. JavaScript example: ``` function generateCodeVerifier(length = 128) { const array = new Uint8Array(length); window.crypto.getRandomValues(array); return btoa(String.fromCharCode.apply(null, array)) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } async function generateCodeChallenge(codeVerifier) { const encoder = new TextEncoder(); const data = encoder.encode(codeVerifier); const digest = await crypto.subtle.digest('SHA-256', data); return btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } ``` ## Step 2: Build Build the authorization URL and redirect the user. Example URL (ensure all parameters are URL-encoded). ``` https://auth.socialchorus.com/oauth/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback& scope=openid+profile+feeds.read& state=YOUR_RANDOM_STATE& code_challenge=YOUR_CODE_CHALLENGE& code_challenge_method=S256& program_id=YOUR_PROGRAM_ID& response_type=code& response_mode=query ``` Required parameters: | Parameter | Description | | --- | --- | | `client_id` | Your app's Client ID | | `redirect_uri` | Call back URI | | `scope` | One or more scopes (space-delimited, use + for URLs) | | `state` | CSRF nonce | | `code_challenge` | SHA-256 hash of the `code_verifier` | | `code_challenge_method` | Must be `S256` | | `program_id` | Your program ID | | `response_type` | `code` | | `response_mode` | `query` | ## Step 3: Handle Handle the redirect. After user login, the app is redirected to: ``` https://yourapp.com/callback?code=AUTH_CODE&state=YOUR_RANDOM_STATE ``` Extract the `code` and validate the returned `state` matches the original. If `state` does not match, terminate the flow. ## Step 4: Exchange Exchange the code for an access token. Curl example: ``` curl -X POST https://auth.socialchorus.com/oauth/token \ -F grant_type=authorization_code \ -F client_id=YOUR_CLIENT_ID \ -F code=AUTH_CODE_FROM_REDIRECT \ -F redirect_uri=https://yourapp.com/callback \ -F code_verifier=ORIGINAL_CODE_VERIFIER ``` Sample response: ``` { "access_token": "ACCESS_TOKEN_HERE", "refresh_token": "REFRESH_TOKEN_HERE", "expires_in": 7200, "token_type": "Bearer", "scope": "openid public", "realm": "program:1" } ``` ## Refreshing Access Tokens Use this call to get a new access token using the refresh_token: ``` curl -X POST https://auth.socialchorus.com/oauth/token \ -F grant_type=refresh_token \ -F client_id=YOUR_CLIENT_ID \ -F refresh_token=YOUR_REFRESH_TOKEN ```