Overview
This article explains how to test the Authorization Code Flow with Postman.
Applies To
- Postman
- Authorization Code Flow
Solution
Follow the steps below to test the Authorization Code Flow using Postman:
- Call the /authorize endpoint to initiate the authorization code flow
- From the redirection to the /u/login endpoint, capture the
state
parameter - Make a POST request to the /u/login endpoint
- In the request, use the
state
parameter captured in step #2 in both the Request Body and Request Parameters - In the x-www-form-urlencoded body of the request, include the
username
andpassword
- From the response
Location
header, capture the newstate
parameter - Make a GET request to the /authorize/resume endpoint, using the
state
parameter captured in step #4 - Retrieve the
authorization code
from the response - Exchange the
authorization code
for a token by sending a POST request to the /oauth/token endpoint
Use the Postman collection provided below to simplify the process.
Before running the Postman collection, ensure the following environment variables are configured in Postman:
auth0_domain
:<The Auth0 domain, e.g., tenant-name.auth0.com>
- auth0_client_id:
<The Client ID of the Auth0 application>
- redirect_uri:
<The Redirect URI configured in the Auth0 application, e.g., http://localhost:3000/callback>
To use the Postman collection for testing the Authorization Code Flow:
- Save the below provided JSON definition as AuthCodeFlow.json.
- Open Postman and navigate to File > Import.
- Select the AuthCodeFlow.json file to import the collection.
- Ensure the environment variables listed above are correctly set in the active Postman environment.
- Run the collection.
NOTE: Performing the interactive portion of the Authorization Code Flow (i.e., calls to the /authorize endpoint) directly within Postman can be unreliable. The Postman collection is designed to handle a direct username
and password
submission compatible with the New Universal Login experience, but may fail if the authentication flow encounters variations such as:
- Classic Universal Login is used.
- Identifier First login flow is enabled.
- Multi-Factor Authentication (MFA) is triggered. (MFA stands for Multi-Factor Authentication and should be defined if this is its first use in the article).
- A consent screen is presented.
- A session cookie is present, causing the login prompt to be skipped.
- An Action script within Auth0 redirects the flow.
- Other changes or customizations to the interactive login process.
A more resilient method for testing involves obtaining the authorization code through a standard browser and then using Postman to exchange this code for tokens. This approach accommodates any authentication prompt or variation presented to the user.
To obtain the authorization code using a browser and then exchange it in Postman:
- Ensure the <redirect_uri> (as configured in the environment variables and listed in the Auth0 application’s Allowed Callback URLs) is effectively inactive for this manual test. For example, if the <redirect_uri> is http://localhost:3000/callback, ensure no local application is running and listening on that address. An active listener could automatically intercept and use the authorization code.
- Open the browser’s Developer Tools and select the Network tab.
- In the browser’s address bar, manually construct and navigate to the /authorize endpoint URL. Replace the placeholders with the actual values:
https://<auth0_domain>/authorize?response_type=code&client_id=<auth0_client_id>&redirect_uri=<redirect_uri>
- Complete the authentication and authorization steps as prompted in the browser (e.g., login, consent).
- After successful authorization, the browser will attempt to redirect to the specified <redirect_uri>. This redirect may result in a browser error page if no service is listening at that address, which is expected for this manual method. In the Developer Tools Network tab, find the request made to this <redirect_uri>.
- From the full URL of this redirect request (often visible in the “Headers” section for the request in Developer Tools), extract the value of the code query parameter. This is the authorization code.
- In Postman, create a new request. Make a POST request to the token endpoint: https://<auth0_domain>/oauth/token.
- Include the following parameters in the body of this POST request, typically formatted as x-www-form-urlencoded:
- grant_type:
authorization_code
- client_id:
<auth0_client_id>
- code:
<authorization_code_obtained_in_step_6>
- redirect_uri:
<redirect_uri>
``
Save the following collection as “AuthCodeFlow.json” and import it into Postman:
{
"info": {
"_postman_id": "0bea1c8c-313e-4156-985d-74c11539f428",
"name": "Auth Code Flow",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "15882021"
},
"item": [
{
"name": "1. Get to /authorize",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"GetState\", function () {",
" console.log(`Retrieving STATE...`)",
" let state = pm.response.headers.get('Location');",
" state = state.slice(state.lastIndexOf('=') + 1);",
" pm.environment.set(\"state\", state);",
" console.log(`Setting STATE (${state}) as environmental variable.`);",
" postman.setNextRequest(\"2. Post to /u/login\");",
"});"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"followRedirects": false
},
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://{{auth0_domain}}/authorize?response_type=code&client_id={{auth0_client_id}}&redirect_uri={{redirect_uri}}",
"protocol": "https",
"host": [
"{{auth0_domain}}"
],
"path": [
"authorize"
],
"query": [
{
"key": "response_type",
"value": "code"
},
{
"key": "client_id",
"value": "{{auth0_client_id}}"
},
{
"key": "redirect_uri",
"value": "{{redirect_uri}}"
}
]
}
},
"response": []
},
{
"name": "2. Post to /u/login",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"GetResumeState\", function () {",
" console.log(`Retrieving RESUME_STATE...`)",
" let resume_state = pm.response.headers.get('Location');",
" resume_state = resume_state.slice(resume_state.lastIndexOf('=') + 1);",
" pm.environment.set(\"resume_state\", resume_state);",
"});"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"followRedirects": false
},
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "username",
"value": "b@b.com",
"type": "text"
},
{
"key": "password",
"value": "1234",
"type": "text"
},
{
"key": "state",
"value": "{{state}}",
"type": "text"
}
]
},
"url": {
"raw": "https://{{auth0_domain}}/u/login?state={{state}}",
"protocol": "https",
"host": [
"{{auth0_domain}}"
],
"path": [
"u",
"login"
],
"query": [
{
"key": "state",
"value": "{{state}}"
}
]
}
},
"response": []
},
{
"name": "3. Get to /resume",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"GetCode\", function () {",
" console.log(`Retrieving CODE...`)",
" let code = pm.response.headers.get('Location');",
" code = code.slice(code.lastIndexOf('=') + 1);",
" pm.environment.set(\"code\", code);",
"});"
],
"type": "text/javascript"
}
}
],
"protocolProfileBehavior": {
"followRedirects": false
},
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://{{auth0_domain}}/authorize/resume?state={{resume_state}}",
"protocol": "https",
"host": [
"{{auth0_domain}}"
],
"path": [
"authorize",
"resume"
],
"query": [
{
"key": "state",
"value": "{{resume_state}}"
}
]
}
},
"response": []
},
{
"name": "4. Exchange CODE against a TOKEN",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"GetToken\", function () {",
" console.log(`Retrieving TOKENS...`)",
" let tokens = pm.response.json();",
" console.log(tokens);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "grant_type",
"value": "authorization_code",
"type": "text"
},
{
"key": "client_id",
"value": "{{auth0_client_id}}",
"type": "text"
},
{
"key": "code",
"value": "{{code}}",
"type": "text"
},
{
"key": "redirect_uri",
"value": "{{redirect_uri}}",
"type": "text"
},
{
"key": "audience",
"value": "",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "https://{{auth0_domain}}/oauth/token",
"protocol": "https",
"host": [
"{{auth0_domain}}"
],
"path": [
"oauth",
"token"
]
},
"description": "This is the OAuth 2.0 grant that regular web apps utilize in order to access an API. Use this endpoint to exchange an Authorization Code for an Access Token."
},
"response": []
}
]
}