Postman pre-request scripts for authenticated API Development
Tags: laravel, postman, api, authentication
Published: 2021-04-07 07:10:58

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68la3nphemaglts0ci04.png)

This is something I recently discovered and found very useful in my daily work so I think it's worth sharing.

Currently I'm locally developing an JSON API. It's build with Laravel, which doesn't really matter within this context, as this post about the API and Postman. 
A key characteristic of this API is **most endpoints  are only accessible for authenticated users**, which I guess, is a common thing. The authentication system itself is using a bearer token. 

Of course every API developing client provides an easy way to set the required headers easily, so does Postman:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb3cfoj6h3n7y4b8veo1.png)

But as a project grows, the amount of preconfigured requests grows. 
That's where environment variables might come into play as a very handy tool. It's an easy way to e.g. provide the access token **once** for a collection of requests. So you only have to change a single, central variable for all requests that are configured to use the environment variable as its Bearer Token.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lre4o95mqess7b8mxydo.png)


### The problem

But as matter of fact, within the current stage of development I am in need to reset my database multiple times a day and it gets seeded with fresh data each time. 
While doing this, my access token gets invalid so I need to go back to my login route, make a login request, copy the returned access token and store it in my environment variables.
This might not sound like much, but it can be annoying and is something that holds me back from resetting and reseeding my database. Something a developer should not be afraid of in my opinion. 
Until I got behind the use of pre-request scripts for this kind of tasks.


## Utilizing pre-request scripts
Postman provides this awesome feature of performing any scripts before actually sending the actual configured request.
By setting up an easy request to check if my currently stored access token from the environment variables is still valid, I'm able to handle the resetting of it completely behind the scenes.

First of all, I'm making a basic request to check if my access token stored in the environment variable is still valid by accessing a route which definitly needs authentication.


```js
// checking if we are logged in 
pm.sendRequest({
    url: 'https://api.yourproject.test/v1/auth/check',
    method: 'GET',
    header: {
	    'Accept': 'application/json',
        'Authorization':  'Bearer ' + pm.environment.get('access_token')
    },
})
```

If my access token is still valid everything is fine and it will carry on with the actual request.
But if it's not I can use a callback to send another request which will sign me back in and update the returned access token within my environment variables.

```js
// ...
}, function (error, response) {
 if (response.code === 401) {
     // Unauthorized. Log in the user
        pm.sendRequest({
            url: 'https://api.yourproject.test/v1/auth/login',
            method: 'POST',
            header: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: {
                mode: 'raw',
                raw: JSON.stringify({ 
                    email: "user@user.com", 
                    password: "password" 
                })
            }
        }, function (error, res){
            if(!error){
                // Login Successfull. Update access token
                var data = res.json();
                pm.environment.set("access_token", data.access_token);
               
            } else {
                console.log(error);
            }
        });
    }
})
```

The complete script may look like this:

```js
pm.sendRequest({
    url: 'https://api.yourproject.test/v1/auth/check',
    method: 'GET',
    header: {
	    'Accept': 'application/json',
        'Authorization':  'Bearer ' + pm.environment.get('access_token')
    },
}, function (error, response) {
    if (response.code === 401) {
        pm.sendRequest({
            url: 'https://api.yourproject.test/v1/auth/login',
            method: 'POST',
            header: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: {
                mode: 'raw',
                raw: JSON.stringify({ 
                    email: "user@user.com", 
                    password: "password" 
                })
            }
        }, function (error, res){
            if(!error){
                var data = res.json();
                pm.environment.set("access_token", data.access_token);
            } else {
                console.log(error);
            }
        });
    }
})
```

### Drawbacks
A drawback might be, that this lowers the time required to perform a request a little bit, because we are actually performing multiple requests (at leaste two) behind the scenes.
But this is pretty much neglectable, as it's probably only noticeable when running a complete collection of requests and not just a single one.

In my opinion, the advantages clearly outweigh the disadvantages in this case.