Skip to content

Instantly share code, notes, and snippets.

@bcnzer
Last active July 22, 2024 10:59
Show Gist options
  • Save bcnzer/073f0fc0b959928b0ca2b173230c0669 to your computer and use it in GitHub Desktop.
Save bcnzer/073f0fc0b959928b0ca2b173230c0669 to your computer and use it in GitHub Desktop.
Postman pre-request script to automatically get a bearer token from Auth0 and save it for reuse
const echoPostRequest = {
url: 'https://<my url>.auth0.com/oauth/token',
method: 'POST',
header: 'Content-Type:application/json',
body: {
mode: 'application/json',
raw: JSON.stringify(
{
client_id:'<your client ID>',
client_secret:'<your client secret>',
audience:'<my audience>',
grant_type:'client_credentials'
})
}
};
var getToken = true;
if (!pm.environment.get('accessTokenExpiry') ||
!pm.environment.get('currentAccessToken')) {
console.log('Token or expiry date are missing')
} else if (pm.environment.get('accessTokenExpiry') <= (new Date()).getTime()) {
console.log('Token is expired')
} else {
getToken = false;
console.log('Token and expiry date are all good');
}
if (getToken === true) {
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log('Saving the token and expiry date')
var responseJson = res.json();
pm.environment.set('currentAccessToken', responseJson.access_token)
var expiryDate = new Date();
expiryDate.setSeconds(expiryDate.getSeconds() + responseJson.expires_in);
pm.environment.set('accessTokenExpiry', expiryDate.getTime());
}
});
}
@AdamW00d
Copy link

AdamW00d commented Dec 3, 2020

Thank you!

@Solksjaer
Copy link

Solksjaer commented Jan 21, 2021

I modified your code a little, in order to include a KeyCloak refresh token call using Url Encoded Forms.
Also, I included an environment validation, in order to avoid autorefresh in production.

const client_id = "client_id";
const username= "username";
const allowedEnvs = ["localEnv", "dev"]

console.log("Runing on Environment: " + pm.environment.name);

if(allowedEnvs.indexOf(pm.environment.name) == -1){
    console.warn("Token Reload only allowed on: " + allowedEnvs);
    return;
}

var keycloak_url = pm.environment.get("keycloak_url") + "/auth/realms/MY_REALM/protocol/openid-connect/token";

var access_token = pm.environment.get("access_token");
var access_token_expiry = pm.environment.get("access_token_expiry");
var refresh_token = pm.environment.get("refresh_token");
var refresh_token_expiry = pm.environment.get("refresh_token_expiry");

const refreshTokenRequest = {
  url: keycloak_url,
  method: 'POST',
  header: 'Content-Type:application/x-www-form-urlencoded',
  body: {
    mode: 'urlencoded',
    urlencoded: [
        {key: "client_id", value: client_id},
        {key: "client_secret", value: pm.environment.get("client_secret")},
        {key: "refresh_token", value: refresh_token},
        {key: "grant_type", value: 'refresh_token'}
    ]
  }
};

const newTokenRequest = {
  url: keycloak_url,
  method: 'POST',
  header: 'Content-Type:application/x-www-form-urlencoded',
  body: {
    mode: 'urlencoded',
    urlencoded: [
        {key: "client_id", value: client_id},
        {key: "client_secret", value: pm.environment.get("client_secret")},
        {key: "username", value: username},
        {key: "grant_type", value: 'password'},
        {key: "password", value: pm.environment.get("user_password")}
    ]
  }
};

var sendRequest = newTokenRequest;

if (!access_token || !access_token_expiry || 
    !refresh_token || !refresh_token_expiry) {
    console.log('Tokens or expiry dates are missing');
} else if (access_token_expiry <= (new Date()).getTime() && refresh_token_expiry <= (new Date()).getTime()) {
    console.log('Access and Refresh Token expired');
} else if (access_token_expiry <= (new Date()).getTime()) {
    console.log('Access Token expired');
    sendRequest = refreshTokenRequest;
} else {
    sendRequest = null;
    console.log('Token and expiry date are all good');
}

if (sendRequest != null) {
    pm.sendRequest(sendRequest, function (err, res) {
        var responseJson = res.json();
        console.log(err ? err : responseJson);

        if (err == null && responseJson.error == null) {
            console.log('Saving tokens and expiry dates')
            
            pm.environment.set('access_token', responseJson.access_token)
            pm.environment.set('refresh_token', responseJson.refresh_token)
    
            pm.environment.set('access_token_expiry', new Date().getTime() + (responseJson.expires_in * 1000));
            pm.environment.set('refresh_token_expiry', new Date().getTime() + (responseJson.refresh_expires_in * 1000));
        }
    });
}

@Andrielson
Copy link

It works like a charm! Thank you!

@RodolVelasco
Copy link

I can get the oauth2 using postman authorization form included in Authorization tab. I would like to replicate this behaviour on pre request script and do this process automatically. You have any idea? This is to connect to Azure App Registration.

@bo55vxr
Copy link

bo55vxr commented Mar 25, 2021

@RodolVelasco

I can get the oauth2 using postman authorization form included in Authorization tab. I would like to replicate this behaviour on pre request script and do this process automatically. You have any idea? This is to connect to Azure App Registration.

I am using Azure OAuth2 tokens and basically the script is very much as described but changing the POST request.

const echoPostRequest = {
url: 'https://login.microsoftonline.com/<tenant ID>/oauth2/token','
  method: 'POST',
  body: {
    mode: 'formdata',
    formdata: [
        {key: "client_id", value:"<client ID>"},
        {key: "client_secret", value:"<client secret>"},
        {key: "resource", value:"<resource>"},
        {key: "grant_type", value:"client_credentials"}
    ]
  }
};

Hope that helps

@RodolVelasco
Copy link

@bo55vxr thanks for your response.

I am using Azure OAuth2 tokens and basically the script is very much as described but changing the POST request.

const echoPostRequest = {
url: 'https://login.microsoftonline.com/<tenant ID>/oauth2/token','
  method: 'POST',
  body: {
    mode: 'formdata',
    formdata: [
        {key: "client_id", value:"<client ID>"},
        {key: "client_secret", value:"<client secret>"},
        {key: "resource", value:"<resource>"},
        {key: "grant_type", value:"client_credentials"}
    ]
  }
};

Hope that helps

I got it done with this script

var clientId = pm.variables.get("clientId");
var clientSecret = pm.variables.get("clientSecret");
var scope = pm.variables.get("scope");
var urlResource = pm.variables.get("urlResource");
var tenant = pm.variables.get("tenant");
var apiEndpointVersion = pm.variables.get("apiEndpointVersion");
pm.sendRequest({
    url: urlResource + tenant + apiEndpointVersion,
    method: "POST",
    header: [
        'Content-Type:application/x-www-form-urlencoded'
    ],
    body: {
        mode: "urlencoded",
        urlencoded: [
            {key: "client_id", value: clientId},
            {key: "client_secret", value: clientSecret},
            {key: "scope", value: scope},
            {key: "grant_type", value: "client_credentials"}
        ]
    },
},
(error, response) => {
    pm.variables.set("rawIdToken", response.json().access_token);
    pm.variables.set("refresh_token", response.json().refresh_token);
});

Where scope has this format:
22xxxxx-xxxx- ..../.default
Url resource is like:
https://login.microsoftonline.com/
apiEndpointVersion is:
/oauth2/v2.0/token
And the other variables are just their values.

@lukw4l
Copy link

lukw4l commented Apr 7, 2021

This is awesome and works like a charm, thank you very much!
I modified the script a bit (used environment variables as input and a urlencoded body) but this script was a very good starting point for further development.

@beliar91
Copy link

This is super useful thank you! That's the exact thing I was looking for, helped me out a lot :).

@jcgaza
Copy link

jcgaza commented May 15, 2021

Hi, how do I add custom permissions on this script? I keep on getting an Insufficient Scope error on mine because I have permissions setup on my routes.

@tboulord
Copy link

tboulord commented Jul 2, 2021

Thank you, perfectly solve my issue (Just had to adapt with urlencoded mode to fit with Keycloack)

@DanielLaberge
Copy link

DanielLaberge commented Jul 16, 2021

For anyone wanting to use an id_token instead of an access_token, I've adapted this script to talk with AWS Cognito User Pools to exchange a refresh_token for an id_token and access_token. You could use it with most OAuth2 endpoints, not just Cognito.

https://gist.github.com/DanielLaberge/5c311b7adb835efc004fcc8e1ea7822a

Thanks for the original script, @bcnzer

@deniswou
Copy link

Thank you very much, it helped me a lot

@grempe
Copy link

grempe commented Jul 28, 2021

Here's a minor tweak on the Auth0 script that makes use of four environment specific variables you can set. This is useful if you are testing multiple environments, each with different Auth0 credentials. Only the echoPostRequest section is modified.

You'll need to set auth0_domain, auth0_client_id, auth0_client_secret, auth0_audience variables.

const echoPostRequest = {
  url: `https://${pm.environment.get('auth0_domain')}/oauth/token`,
  method: 'POST',
  header: 'Content-Type:application/json',
  body: {
    mode: 'application/json',
    raw: JSON.stringify(
    {
        "client_id": pm.environment.get('auth0_client_id'),
        "client_secret": pm.environment.get('auth0_client_secret'),
        "audience": pm.environment.get('auth0_audience'),
        grant_type:'client_credentials'
    })
  }
};

var getToken = true;

if (!pm.environment.get('accessTokenExpiry') || 
    !pm.environment.get('currentAccessToken')) {
    console.log('Token or expiry date are missing')
} else if (pm.environment.get('accessTokenExpiry') <= (new Date()).getTime()) {
    console.log('Token is expired')
} else {
    getToken = false;
    console.log('Token and expiry date are all good');
}

if (getToken === true) {
    pm.sendRequest(echoPostRequest, function (err, res) {
    console.log(err ? err : res.json());
        if (err === null) {
            console.log('Saving the token and expiry date')
            var responseJson = res.json();
            console.log(responseJson.access_token)
            pm.environment.set('currentAccessToken', responseJson.access_token)
    
            var expiryDate = new Date();
            expiryDate.setSeconds(expiryDate.getSeconds() + responseJson.expires_in);
            pm.environment.set('accessTokenExpiry', expiryDate.getTime());
        }
    });
}

@parksanghun
Copy link

Nice! Thank you!!!

@Glideh
Copy link

Glideh commented Nov 26, 2021

Good script, thx all.
One can also get the expiry from the token (if not returned explicitly by the API):

const payload = JSON.parse(atob(responseJson.access_token.split('.')[1]));
console.log(new Date(payload.exp * 1000));

Details:

  • Split the token by '.'
  • Take the payload (second element between [0]: header and [2]: signature)
  • Base 64 decode the string with atob()
  • JSON.parse() the decoded payload
  • Expiration timestamp can be found in the exp key
  • Eventually exp can be converted to a Date() multiplying it by 1000

@joelrdzdio
Copy link

Very nice, I was struggling trying to do something like this, and then decided to search and see if anybody had done it already. Found it and it works great. Thank you!

@abdurayimov-work
Copy link

Here is my trick:

  1. Created an environment and variable Authorization inside it.
    https://monosnap.com/file/Vn4WvhXMNsnOFPmB4sC8GU4gilfMPz

  2. Added a folder called "User". In folder settings I defined pre-request:
    https://monosnap.com/file/AWMMTcSs6TtJw3Eqet3gMBLmOdcDA5

pm.sendRequest({
    url: 'https://' + pm.variables.get('api_domain') + '/api/auth/login',
    method: 'POST',
    header: {
        'content-type': 'application/json',
    },
    body: {
        mode: 'raw',
        raw: JSON.stringify({ 
            email: pm.variables.get('admin_email'),
            password: pm.variables.get('admin_password'),
            captcha_token: "no_for_local"
        })
    }
}, function (err, res) {
    pm.environment.set("Authorization", "Bearer " + res.json().token);
});
  1. In request created inside this folder I set this header:
    https://monosnap.com/file/H0n2VnrxU1cwriJokXvlJU7I2f6qGl

  2. Each request you created inside this folder will run above script before execution:
    https://monosnap.com/file/KK3qzgDKXj27iQqlCOgdyxDFuBtl9e

@cg-at-bespokenai
Copy link

amazing!

@anantyadunath
Copy link

@bcnzer - I am trying to figure out if similar script could work for auth code flow. I need user to sign in, based on which need to generate the access token. Unfortunately, postman "Authorization" tab does not expose the access_token as variable and they are still working on it (since long 4 years). Have you ever faced this situation? Do you have any workarounds in mind?

@MohammadAbualhasanAnati

It works perfectly! Time & Effort saving
Thanks a lot

@sayuri-sam
Copy link

thx a lot,
I use it in postman pre-request script but unfortunately I couldn't pass the currentAccessToken to the second request
how to do it?

@bo55vxr
Copy link

bo55vxr commented Jan 26, 2023

thx a lot, I use it in postman pre-request script but unfortunately I couldn't pass the currentAccessToken to the second request how to do it?

@sayuri-sam What do you mean, 2nd request? Have you specified the currentAccessToken as a variable in the Authorization tab of the request?

@sayuri-sam
Copy link

sayuri-sam commented Jan 27, 2023

bo55vxr
yes, I use this code as pre-request script in postman.
and I want to pass the value in currentAccessToken to Auth token.

image

the request result
image

can you figure it out?

@sysqo82
Copy link

sysqo82 commented Jan 27, 2023

@sayuri-sam you need to use double curly braces {{currentAccessToken}}

@bo55vxr
Copy link

bo55vxr commented Jan 27, 2023

@sayuri-sam you need to use double curly braces {{currentAccessToken}}

^^^ This...

@tester-at-bmi
Copy link

@Solksjaer thanks for the snippet just what i needed 👍

@gustavocoleta
Copy link

Tks! 👍

@troyinsight
Copy link

Hi @anantyadunath. Quick question, did you ever get auth code flow working with Postman?

@anantyadunath
Copy link

anantyadunath commented Jun 10, 2023 via email

@mahAzin
Copy link

mahAzin commented Jun 25, 2023

Hi, Do you have a solution if our authorization is with Grant Type: Authorization Code (with PKCE).
we don`t use client secret, and we put it blank.
I turn on Auto-refresh token and every API works great, but in monitor I get No response.

Screenshot 2023-06-25 122147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment