Add Login Using the Authorization Code Flow with PKCE

Here’s the revised version of Add Login Using the Authorization Code Flow with PKCE for Login 3.0, tailored for the UPBOND framework:


Add Login Using the Authorization Code Flow with PKCE in Login 3.0

The Authorization Code Flow with PKCE enhances security for native, mobile, and single-page applications (SPAs) that cannot securely store a client secret. This guide explains how to implement this flow using Login 3.0.


Overview

  • Use PKCE to secure public applications like SPAs or native apps.

  • Following a successful login, your app will receive:

    • An ID Token with basic user information.

    • An Access Token to call APIs.

    • Optionally, a Refresh Token for long-lived sessions.

For more details on PKCE, see Authorization Code Flow with PKCE in Login 3.0.


Prerequisites

Before implementing PKCE, contact the UPBOND team to:

  1. Register Your Application:

    • Specify your application type: Native, Mobile, or SPA.

    • Provide callback URLs (e.g., https://yourApp/callback).

    • Request required scopes and permissions.

    • Ensure your application’s grant types include authorization_code.

  2. Register Your API (if needed):

    • Enable required scopes.

    • Configure API access settings.

The UPBOND team will set up and configure your Login 3.0 tenant for PKCE-based authentication.


Implementation Steps

1. Create Code Verifier

Generate a cryptographically secure code_verifier, a Base64-encoded string. Below are examples for different languages:

JavaScript Example:

function base64URLEncode(str) {
    return str.toString('base64')
        .replace(/\\+/g, '-')
        .replace(/\\//g, '_')
        .replace(/=/g, '');
}
var verifier = base64URLEncode(crypto.randomBytes(32));

Java Example:

SecureRandom sr = new SecureRandom();
byte[] code = new byte[32];
sr.nextBytes(code);
String verifier = Base64.getUrlEncoder().withoutPadding().encodeToString(code);

2. Create Code Challenge

Generate a code_challenge by hashing the code_verifier using SHA-256 and encoding it in Base64.

JavaScript Example:

function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));

Java Example:

byte[] bytes = verifier.getBytes("US-ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bytes, 0, bytes.length);
byte[] digest = md.digest();
String challenge = Base64.encodeBase64URLSafeString(digest);

3. Redirect User for Authorization

Send the user to the Login 3.0 authorization endpoint:

https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope={scope}&
    state={state}

Replace placeholders with your application’s details:

  • client_id: Application’s client ID.

  • redirect_uri: Registered callback URL.

  • scope: Requested scopes (e.g., openid profile email).


4. Exchange Authorization Code for Tokens

Send a POST request to the /oauth/token endpoint with the following parameters:

curl --request POST \\
  --url 'https://{yourDomain}/oauth/token' \\
  --header 'content-type: application/x-www-form-urlencoded' \\
  --data grant_type=authorization_code \\
  --data 'client_id={yourClientId}' \\
  --data 'code_verifier={yourCodeVerifier}' \\
  --data 'code={yourAuthorizationCode}' \\
  --data 'redirect_uri={yourCallbackUrl}'

Response:

{
  "access_token": "eyJz93a...k4laUWw",
  "refresh_token": "GEbRxBN...edjnXbL",
  "id_token": "eyJ0XAi...4faeEoQ",
  "token_type": "Bearer",
  "expires_in": 86400
}

5. Use Access Token to Call APIs

Include the Access Token in the Authorization header when making API requests:

curl --request GET \\
  --url 'https://{yourApi}/endpoint' \\
  --header 'Authorization: Bearer {accessToken}'

Advanced Use Cases

Request User’s Profile:

https://{yourDomain}/authorize?
    response_type=code&
    code_challenge={codeChallenge}&
    code_challenge_method=S256&
    client_id={yourClientId}&
    redirect_uri={yourCallbackUrl}&
    scope=openid%20profile%20email

Last updated

Was this helpful?