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.
- 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.
- Always use
S256
for thecode_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.
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(/=+$/, '');
}
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 |
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.
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"
}
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