
Photo by Rubaitul Azad
Postman — Pre-Request scripting
- August 16, 2023
- Recommended, Web, Tools, Innovation
Table of Contents
I work with APIs a lot, so I decided to solve an annoying problem: updating request tokens automatically. Here is how I did it.
I want to preface this guide by saying this script works for most, but not all, of my APIs. The main difference is the login response, which can vary depending on the month’s flavor.
{
"id": 2,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2ZjbXNhcGkudGVzdC9hcGkvdjEvYXV0aC9sb2dpbiIsImlhdCI6MTY5MjE3MjE1OCwiZXhwIjoxNjkyMTc1NzU4LCJuYmYiOjE2OTIxNzIxNTgsImp0aSI6ImZZdmJ3enBDZzFpVUNKT1AiLCJzdWIiOiIyIiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.9bTpzDT2FjX_JhYb0mcYpKWWaS5WfeQa7b7h7uL2AUY",
"token_type": "bearer",
"expires_in": 3600
}
Common for all login responses is that it needs a token and an expiration timer (in seconds). The user’s ID and a token type are often included as well, but these are optional.
In the above example, a JWT (JSON Web Token) is the token, and we’re using Bearer for authorization.
The first thing we need is to define the variables we need. I don’t set any default values as it’s unnecessary. If the script has run before, these variables are in the collection variables section of Postman for the collection the script is in.
let tokenDate = new Date(2010, 1, 1)
let tokenTimestamp = pm.collectionVariables.get('timestamp')
let userId = pm.collectionVariables.get('userid')
let token = pm.collectionVariables.get('token')
let expiresInTime = pm.collectionVariables.get('expires_in')
Next, we need to decide if a new token is required. This can be done in many ways, but I prefer the timestamp check because it allows me to run the check the fastest. Worst case scenario, I will need to manually clear the token and rerun the script if it has expired.
To check if the token has expired, we need to compare the timestamp of when the token was generated to the current timestamp to find out how much time has elapsed and see if it’s above the expires_in value from the login response.
if (tokenTimestamp) {
tokenDate = Date.parse(tokenTimestamp)
}
if (!expiresInTime) {
expiresInTime = 1500000 // Set default expiration time to 15 minutes
}
now = Date.now()
let elapsed = (now - tokenDate) / 1000
Note that the javascript date returns a value in microseconds and not Unixtime, so we need to convert it to seconds in order to compare it to the expires_in value — which is in seconds.
Next, we need to find out if we need to get a new token, which is a reasonably simple check on elapsed time and whether or not we already have a token.
if (elapsed >= expiresInTime || token === null || token === undefined) {
let url = pm.environment.get('host')
url += ':' + pm.environment.get('port')
url += pm.environment.get('uri')
pm.sendRequest(
{
url: url + '/auth/login',
method: 'POST',
header: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: {
mode: 'raw',
raw: {
email: pm.environment.get('username'),
password: pm.environment.get('password'),
},
},
},
function (err, res) {
if (res.code === 200) {
let response = res.json()
pm.collectionVariables.set('token', response.access_token)
pm.collectionVariables.set('timestamp', new Date())
pm.collectionVariables.set('userid', response.id)
pm.collectionVariables.set('expires_in', response.expires_in)
console.log('Token set: ' + response.access_token)
} else {
console.log(res)
throw new Error(
'Login failed with status: ' +
res.status +
' (Code: ' +
res.code +
')',
)
}
},
)
}
If we don’t have a token or it has expired, start the process of making a login request. We build a URL using environment variables, which is a good time to mention you should always be using environments in Postman. I’ve set up a local, staging, and prod environment and defined host port and uri in all of them for each environment.
We also need login credentials, which should always be defined as environment variables, as the login details may differ, and because you don’t want credentials in your code.
We send the request using pm.sendRequest which takes a request object (similar to many other javascript HTTP request frameworks), and as the second parameter, it takes a callback with the response in. We check for code 200; if we get it, we set the variables from the response. If we get an error, we log the response object and throw a javascript error to stop further execution.
I set this pre-request script on my Auth folder for my Postman APIs to make it easier for me to test and browse authorized endpoints. Sometimes, I need to make small changes to which response fields I read from, but for the most part, the script remains unchanged.
Pre-request scripts are powerful tools, and although I wish I could have more “files” for all my other scripts (for better organization), this one works well.
Try it out, and let me know what you think!
Get the complete script on my GitHub.
Tags:
Related Posts

NoTTL - A new caching concept?
- June 21, 2021
- Recommended, Innovation, Web, Caching, Software architecture, Nottl
There is an old joke in IT that goes “The 2 hardest things in programming is Naming, Caching, and off by one error’s”. I’ve often said …
Read More
Why you should be using Go-Task
- March 3, 2023
- Recommended, Web, Tools, Innovation
In today’s tooltip I’ll be showcasing go-task. It’s a tool designed to make executing terminal commands or even lists of commands needed for …
Read More
Hugo: Two years with a flat-file serverless website
- May 14, 2023
- Recommended, Innovation, Framework, Gohugo, Flat file, Web, Cms
In May 2021, I was fed up with my website. It was nothing more than a business card with contact information, and it cost me $20 a month to host it.
Read More