I'm available to work on new projects starting July 2020! Get in touch!

Back to post list

Automatically set Authentication tokens in Postman requests

25-01-2020

When working with APIs it's common to have to set a Bearer token on each request. The usual workflow would be to create an authentication request.

In Postman it would look somethig like this:

This endpoint will usually return a new valid token:

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwibmJmIjoxNTc5OTU2Mzg1LCJleHAiOjE1Nzk5NTY5ODUsImlhdCI6MTU3OTk1NjM4NX0.pF87gUKjXlgI7oyuW2TwtxkkayHadm7NkGzwEcYXOGfehJNoLk4hvGYSvsenYYP9ClXS8GwjRQLMs8iw1putcA"
}

Now we would have to manually copy this token, and in an actual request to the application, in the Authentication tab, paste it under the Token field (when the type Bearer Token has been selected).

Finally, we can now send the request to the application with a valid Bearer token. Sounds tiring isn't it?

Wait, what's Postman?

Postman is a collaboration platform for API development. Postman's features simplify each step of building an API and streamline collaboration so you can create better APIs—faster.

Intermediate solution

One solution would be to create a new global variable, and paste the created token under this field.

We can then use this variable dynamically under the Type field: using {{jwttoken}}.

We can do even better: create a new collection, and set the Authentication configuration on this folder. Right click on the collection and select edit.

This will make every request under this collection use this Bearer token authentication. This still requires tidious copy-pasting the token in the global variable every time it expires. We can do better!

Final lazy-mode solution

This solution automates everything, every request will authenticate automatically. No copy pasting required at all. This will use the very handy Pre-request Script feature of Postman.

The setup

For this to be efficient, lets setup a new Environment with some variables:

  • authService: The full URL to the service handling the authentication,
  • username & password: Your username and password,
  • gatewayBaseUrl: in a microservice world this is the entrypoint of your application(s). If not using microservices just consider this the baseUrl.

These will be used in our fancy script.

Code!

var authServiceUrl = pm.environment.get('authService');
var gatewayBaseUrl = pm.environment.get('gatewayBaseUrl');
var username = pm.environment.get('username');
var password = pm.environment.get('password');

var sdk = require('postman-collection');

var isValidTokenRequest = new sdk.Request({
    url: gatewayBaseUrl + "/api/item/items", // Use an endpoint that requires being authenticated
    method: 'GET',
    header: [
        new sdk.Header({
            key: 'content-type',
            value: 'application/json',
        }),
        new sdk.Header({
            key: 'acccept',
            value: 'application/json',
        }),
        new sdk.Header({
            key: 'Authorization',
            value: 'Bearer ' + pm.globals.get("jwttoken"),
        }),
    ]
});

pm.sendRequest(isValidTokenRequest, function (err, response) {
    if (response.code === 401) {
        refreshToken();
    }
});

function refreshToken() {
    var tokenRequest = new sdk.Request({
    url: authServiceUrl,
    method: 'POST',
    header: [
        new sdk.Header({
            key: 'content-type',
            value: 'application/json'
        }),
        new sdk.Header({
            key: 'acccept',
            value: 'application/json'
        }),
    ],
    body: {
        mode: 'raw',
        raw: JSON.stringify({
            username: username,
            password: password
        })
    } 
  });

  pm.sendRequest(tokenRequest, function (err, response) {
      if (err) {
          throw err;
      }
      
      if (response.code !== 200) {
          throw new Error('Could not log in.');
      }
      
      pm.globals.set("jwttoken", response.json().token);
      console.log(`New token has been set: ${response.json().token}`);
  });
}

That's it! Let's explain what this do.

First, we initialise some variables coming from our environment.

We then import the postman collection SDK.

We now prepare the first request that will be checking if we have a valid token already set or not. This is good to not request a fresh token on every single request. If we get a 401 response, we call a refreshToken() function.

We finally define this refreshToken function that will request your authentication endpoint that generates a new fresh token given the username/password set as environment variables. It will set the global variable jwttoken that is used in the Authentication configuration.

You can use the script on the collection so every request in this collection performs this logic and this automatically gets a fresh token.

Having seen this script, you can now customise it based on your application, different authentication endpoint request/response etc.

Conclusion

We were able to leverage several features in Postman, global variables, environments, environment variables, and pre-request scripts to achieve a useful time-saving solution.

A lot more can be done using the Postman SDK, find out what on their documentation.

I'm available to work on new projects starting July 2020! Get in touch!

Duplicate a PostgreSQL schema