Skip to main content

Authorization Code with PKCE

The purpose of the Authorization Code flow with PKCE is to acquire an Access Token, which can be added as Bearer token to REST calls made towards a Resource Server.

This flow should be used by single-page (SPA) and other client-side applications which cannot store a client secret as it could easily be extracted.

Classic Web applications which have server-side processing may use the basic Authorization Code flow without PKCE instead. Use the Client Credentials for machine-to-machine use cases.

Authorization Code flow with PKCE

  1. The user clicks Login in the App.

  2. The App has to generate 2 codes for PKCE:

    1. code_verifier - must be a random String and at least 43 characters long.
    2. code_challenge - URL-safe base64 encoded SHA256 hash of the code_verifier. The codes ensure message integrity. Even if an attacker intercepts the Authorization Code (see step 6), they won't be able to obtain an Access Token as they also need the code_verifier and the code_challenge.

    Example Angular code to generate code_challenge from code_verifier:

    import * as CryptoJS from 'crypto-js';

    private generateCodeChallenge(code_verifier: string): string {
    return this.base64URL(CryptoJS.SHA256(code_verifier));
    }

    private base64URL(value) {
    return value.toString(CryptoJS.enc.Base64)
    .replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
    }

  3. The App redirects the user to the Identity Cloud Authorization endpoint. Example URL (HTTP GET) 1:


    <https://yourinstance.id.nevis.cloud/auth/oauth2/authorize>
    ?response_type=code
    &code_challenge=U2ZQIMYt1dJ-Vft83__UiJihGh40zoXX5GoOnsDo4BE
    &code_challenge_method=S256
    &client_id=dbd00f622a1f005f
    &redirect_uri=<https://app.my-company.com>
    &scope=openid%20offline_access

    See Authorization endpoint for a description of the query parameters.

  4. Identity Cloud shows a login page.

  5. The user authenticates by entering their credentials.

  6. Upon successful authentication, the authorization endpoint stores the codechallenge, generates an _Authorization Code, and redirects the user to the return_uri. The code is added as a query parameter. Example URL (HTTP GET) 1:


    <https://app.my-company.com?code=WyZIgDiGQ0DIvbZM7vmBW2ADw6hzwekZac0oe_ucfYo>

  7. The App sends the Authorization Code to the Identity Cloud Token endpoint, together with the code_verifier (from step 2). Example URL (HTTP POST) 1:


    grant_type=authorization_code
    &client_id=dbd00f622a1f005f
    &code_verifier=DP0DueG8PR9rj6ITsWg7YHEUEg5QPttl84wq6xA7NNo9z0vLmCWNTYPKYrjCC9hh
    &code=WyZIgDiGQ0DIvbZM7vmBW2ADw6hzwekZac0oe_ucfYo
    &redirect_uri=https%3A%2F%app.my-company.com

    See Token endpoint for a description of the query parameters.

  8. The token endpoint verifies the code_challenge (received in step 3) and the code_verifier (received in step 7).

  9. The token endpoint returns an Access Token. Depending on the scopes requested in step 2 additional tokens will be returned:

    1. ID Token: scope openid
    2. Refresh Token: scope offline_access

    Example JSON response 1:

    {
    "access_token":"...",
    "refresh_token":"...",
    "id_token":"...",
    "token_type":"Bearer",
    "expires_in":3600
    }

1 line-breaks have been added to make the example more readable.