Postman quick tricks
Tags: postman, javascript, node, jsrsaassign
Published: 2020-11-22 10:21:23

**Postman** is an awesome tool. It lets you automate a lot of the work when you are playing with API's. But are you really getting the most of out it?

I'm going to show some little tricks that can help you save valuable minutes in your day-to-day workflow.


> If you want to reproduce these tricks, you will need to have installed [nodejs](https://nodejs.org/en/) and [Postman Collection SDK](https://www.postmanlabs.com/postman-collection/index.html) in your computer.



## Scenario #1: Rename all the items of a collection adding a prefix sequence index

Sometimes we are working on a large postman collection and **we want to be explicit on what order of execution the user should follow**.

Adding a prefix to each item of the collection seems like a good idea, but if we have several items in our collection, doing this manually is pretty boring..., there has to be a way to do it quickly...

Indeed! There is an easy way! Here is the code for the impatient:

Create a file called **rename_items_collection.js** and paste the following code:

```javascript
// Import Postman Collection SDK
const fs = require('fs');
const {Collection} = require('postman-collection');
const FILENAME = './sample-collection.json';
const SEP = '-';

// Read our postman collection file
const myCollection = new Collection(require(FILENAME));

// Update list of items renaming each of them with a sequence prefix
myCollection.items.members = myCollection.item.members.map((item,idx) => item = {...item, name: `${idx+1} ${SEP} ${item.name}`});

// Output collection content
console.log(JSON.stringify(myCollection.toJSON()));
```

Open a terminal and type:

```sh
node rename_items_collection.js
```

You will see in your screen the contents of the collection. If you want to save it, run this one:

```sh
node rename_items_collection.js > renamed_collection.json
```

Now, you can import **renamed_collection.json** in your Postman App and you will see each item name prefixed with an index.

## Scenario #2: Make requests with fake data

You need to test your API with some random and fake data, but you don't want to implement some function to randomize each data type.

Did you know that Postman has **dynamic variables** based on [faker.js](https://www.npmjs.com/package/faker) mocking data library?

The best part: There is some "Finance" data you can mock. Here are some examples:

- Random **IBAN account number** ? : use `{{$randomBankAccountIban}}`
- Random **ISO-4217 currency code** (3-letter) ? : use `{{$randomCurrencyCode}}`
- Random **Bitcoin address** : use `{{$randomBitcoin}}`

Take a look of [the complete variable list](https://learning.postman.com/docs/writing-scripts/script-references/variables-list/).

If you want to use these variables in a **Pre-request** section, you should use it as in the following example:

```javascript
// Generate a random UUID

// This works
var uuid = pm.variables.replaceIn('{{$guid}}');

//This won't work
var uuid = {{$guid}}
```


## Scenario #3: Check JWT claims with Javascript within Postman

I don't know you, but when I work I have several applications opened, sometimes too many.

When I have to test or debug an API that makes use of OAuth 2.0 with **JWT**, sometimes I need to check if a request has proper data in the JWT. It's useful to remember **Occam's Razor** :

> " of two competing theories, the simpler explanation of an entity is to be preferred"

What does it have to do with this scenario?

When you are troubleshooting some requests, we tend to look for complex assumptions. It's better to start with the easiest ones, which are the most frequent. So, let's do it.

Imagine we have the following JWT:

```javascript
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```

As we know, every JWT consists of 3 parts (the **'.'** "*splits*" each part). I've just given you a clue... .

If you want to know the claim content (Ignoring verifing the JWT signature), can you do it?

Yes! with 2 lines of Javascript!

Put the following lines in the **Pre-request** tab on the request you want to check

```javascript
var [jose_header,payload,] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c".split('.');
console.log(JSON.parse(atob(payload)))
```
> with the **atob** javascript native function we can decode Base64

> If you have the JWT content in a variable called **assertion** you can substitute the string with the following example



```javascript
var [jose_header,payload,] = pm.variables.get("assertion").split('.');
console.log(JSON.parse(atob(payload)))
```

Here you have a reminder diagram on Postman supported variables and their scopes:

![Postman Variables](https://assets.postman.com/postman-docs/Variables-Chart.png)


When you run this code, you will see in the **Postman console**:

```javascript
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
```

## Scenario #4: Signing JWT tokens directly within Postman


Maybe you know this amazing cryptography tool called [jsrsasign](https://github.com/kjur/jsrsasign) : It supports a lot of the common tasks you have to do when working with **secure APIs**:

- **RSA/RSAPSS/ECDSA/DSA** signing/validation
- ASN.1
- **PKCS#1/5/8** private/public key
- **X.509 certificate**
- CRL
- OCSP
- CMS SignedData
- TimeStamp
- CAdES JSON Web Signature/Token/Key (JWS/JWT/JWK)

There are multiple ways to use this library within Postman. We, as developers, should evaluate which way is better for our use case. Here you have two ways of using **jsrsasign**:


### Load jsrsasign from external URL

This is the simplest way to use it: [postman-util-lib](https://joolfe.github.io/postman-util-lib/). Kudos to **joolfe**.

> If you want to try this way, on the **postman-util-lib** website there is a good documentation on how to use it


But here are two corner cases you can think about:
- Should we trust a site we cannot control?
- What if you work in a restricted environment where every url needs to "be validated" beforehand in the firewall of your organization?

Thinking about those scenarios, I want to share with you a way of using this awesome library locally.

### Load jsrsasign locally

So, let's do it!

#### Trial #1: Read the library from a local file

Unfortunately, this is not possible yet in Postman :-( . Take a look this [**issue**](https://github.com/postmanlabs/postman-app-support/issues/7210) in Postman App Support.

#### Trial #2: Serve the library from localhost

1. Let's grab the file from [https://raw.githubusercontent.com/kjur/jsrsasign/master/jsrsasign-all-min.js](https://raw.githubusercontent.com/kjur/jsrsasign/master/jsrsasign-all-min.js).

2. Let's serve this file from **localhost**. We can use **http-server** nodejs package to do it. If you prefer to serve the file with another method, [there are a ton of them](https://gist.github.com/willurd/5720255).

```bash
mkdir jsrsasign_library
cd jsrsasign_library
wget https://raw.githubusercontent.com/kjur/jsrsasign/master/jsrsasign-all-min.js
npm i -g http-server
http-server . -p 8080
```
> From your browser you can reach the file at **http://localhost:8080/jsrsasign-all-min.js**

> Next, assume you have a variable in the Postman environment called **sign_secret** . If you just want to try it, you can substitute in the following code with a string (Although it's a bad practice)

3. Now go to Pre-Request tab , and copy the following

```javascript
var URL_local_jsrsasign = "http://localhost:8080/jsrsasign-all-min.js"
if(!pm.globals.get("jsrsasign")) {
    pm.sendRequest(URL_local_jsrsasign ,(err, res) => {
      if(!err){
       pm.globals.set("jsrsasign", res.text());
      }    
    });
}
// Load jsrsasign library in global context
eval(pm.globals.get("jsrsasign"));

const jose_header = {
  "typ": "JWT",
  "alg": "RS256"
};
const payload = {
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

// Sign JWT
var jwt = KJUR.jws.JWS.sign("HS256", jose_header, payload, pm.environment.get("sign_secret"));
console.log(jwt);

// verify JWT
isValid = KJUR.jws.JWS.verify(jwt, pm.environment.get("sign_secret"), ["HS256"]);
```


I hope you find these little tricks useful. Happy hacking!



Cover Photo Credit: <span>Photo by <a href="https://unsplash.com/@barnimages?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Barn Images</a> on <a href="https://unsplash.com/s/photos/tools?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>