## Authorization Code Grant With PKCE For this grant type (read '[*OAuth Grant Types*](/oauth/grant-types)' section), your application will have to redirect users to Passolution's Authorization Server's Authorization URL with following parameters: | Parameter | Description | | --- | --- | | client_id | Your OAuth Client ID | | redirect_uri | Redirect URL that you provided us when requesting OAuth details for your application. | | response_type | 'response_type' parameter should be set to 'code' for Authorization Code Grant Type. | | scope | 'scope' parameter should be set to '*' to request access to all API resources. | | state | 'state' parameter should contain a random string that you store to user's session storage and verify later when handling authorization response received on your Redirect URL endpoint sent as redirect_uri parameter. | | code_challenge | 'code_challenge' parameter value should be Base64 encoded value (URL safe characters) of SHA256 hash of a randomly generated 'Code Verifier'. The Code Verifier should be randomly generated string of length between 43 and 128 characters. Trailing '=' characters as well as any whitespace or line breaks should be removed from the Base64 encoded value.**See code logic below** | | code_challenge_method | 'code_challenge_method' parameter should be set to 'S256' specifying the SHA256 hash algorithm being used. | **state & code_challenge** parameter code logic example: ```javascript const userState = RandomString::generate(); // eg: G8TZWEjUmuWFZgtHZ5gs UserSession::set('user-oauth-state', userState); const codeVerifierLength = 128; const codeVerifier = RandomString::generate(codeVerifierLength); // eg: L5nD...UKbN UserSession::set('user-oauth-code-verifier', codeVerifier); const hashBinary = SHA256::hashAsBinary(codeVerifier); // SHA256 hash as binary data let codeChallenge = Base64::encode(hashBinary); // Base64 encode SHA256 hash // Removing trailing '=' characters and replace URL unsafe characters ('+' & '/') codeChallenge = String::removeFromEnd(codeChallenge, '='); codeChallenge = String::replace(codeChallenge, '+', '-'); codeChallenge = String::replace(codeChallenge, '/', '_'); Redirect::toUrl('https://web.passolution.eu/oauth/authorize?...&state=' + userState + '&code_challenge=' + codeChallenge); ``` Example: ```text https://web.passolution.eu/oauth/authorize?client_id=your-client-id&redirect_uri=https://your-website.example.com/handle-oauth-authorization&response_type=code&scope=%2A&state=random-state-for-user&code_challenge=code-challange&code_challenge_method=S256 ``` At this stage, on our Authorization Server, the user will be asked to login (if not already logged in) and then they will be able to decide if they want to allow access to your application. Once they allow access, they will be redirected to your Redirect URL with following parameters: | Parameter | Description | | --- | --- | | state | This is the random string that you sent when redirecting user to Authorization Server. You should have stored it in user's session storage and should now **confirm that the values received matches the stored value**. | | code | This is authorization code that you can use to get access token as explained in next step. | Example: ```text https://your-website.example.com/handle-oauth-authorization?state=random-state-that-was-sent-for-user&code=authorization_code ``` **state** parameter verification logic example: ```javascript // stored earlier when redirecting user for login const userState = UserSession::get('user-oauth-state'); if(userState == Url::getParameter('state')) { // exchange authorization code for Access Token as described below. } else { throw Exception('OAuth Login: Invalid state parameter received.'); } ``` br To exchange the authorization code (code parameter received on Redirect URL) for Access Token & Refresh Token for the user, you have to make a POST request to Authorization Server's Token URL (https://web.passolution.eu/oauth/token), eg: ```http POST https://web.passolution.eu/oauth/token Content-Type: application/json { "client_id": "your-client-id", "grant_type": "authorization_code", "redirect_uri": "https://your-website.example.com/handle-oauth-authorization", "code": "authorization-code", "code_verifier": "code-verifier" } ``` Data fields used in the request body above are described below: | Parameter | Description | | --- | --- | | client_id | Your OAuth Client ID | | grant_type | 'grant_type' field should be set to 'authorization_code' for the Authorization Code Grant Type | | redirect_uri | Redirect URL of the endpoint where the authorization response was received. | | code | The authorization code received as 'code' parameter to your Redirect URL endpoint | | code_verifier | The Code Verifier (non hashed value) that we randomly generated earlier for user and stored in session storage. | The Token URL endpoint will respond with JSON response containing following fields: ```json { "expires_in": 31536000, "access_token": "eyJ...", "refresh_token": "def..." } ``` | Parameter | Description | | --- | --- | | expires_in | Number of seconds after which the access token will expire. | | access_token | Access Token for the User | | refresh_token | Refresh Token for the User which can be used to generate new Access Token before expiry |