0
votes

I'm trying to setup a Postman Pre-request to get an OAuth token before each request I make to my service.

I've tried to follow various examples and guides related to this and each seems pretty straightforward, though I still have issues with my script as the pre-request script fail.

I'm afraid this is somehow related to the fact that the endpoint I need to call to get the token is on http protocol and not https, as in the Postman console I'm always getting 2 separate requests to the same url, one on https and one on http.

Here is my pre-request script

pm.expect(pm.environment.has('host')).to.be.true;
pm.expect(pm.environment.has('client_id')).to.be.true;
pm.expect(pm.environment.has('client_secret')).to.be.true;
pm.expect(pm.environment.has('username')).to.be.true;
pm.expect(pm.environment.has('password')).to.be.true;

var options = { method: 'POST',
  url: 'http://' + pm.environment.get("host") + '/api/oauth/token',
  headers: 
  { 
 Authorization: 'Basic '+btoa(pm.environment.get("client_id")+':'+pm.environment.get("client_secret")),
 'Content-Type': 'application/x-www-form-urlencoded' 

  },
  form: 
   { 
   grant_type: 'password',
   username: pm.environment.get('username'),
   password: pm.environment.get('password'),
   } 
};

pm.sendRequest(options, function(err, response) {
  console.log(response.json())
});

And here what I see in my Postman console

Postman douple post pre-request on different protocols

As you can see from the picture the first request fails and the second one generates a 401 HTTP response.

If I run the same request outside of the pre-request script as a "regular" postman request on http everything works fine, but on https I get an error as the request is not even made

How can I make my pre-request script working fine?

2
Why not create an initial request just to retrieve the OAuth token, save the result in a variable, then use that variable on another request that actually performs an action? Saves you from having a token retrieval pre-request script all the time. - Mo A
This is basically what I'm doing right now, but this will require me to update the variable every time the token expires, which I wanted to avoid ideally - Kerruba

2 Answers

3
votes

I finally figured out what the problem was.

There were multiple problems with the pre-script:

1) The double response was actually related to a double pre-script, one at the collection level and on at folder level inside the collection.

2) The request itself had to be changed because many parts were incorrect. As Mo a was saying the headers key was wrong and need to be header, but also the body is not correct as it require specific format.

Here you can find the new request working correctly

pm.expect(pm.environment.has('host')).to.be.true;
pm.expect(pm.environment.has('client_id')).to.be.true;
pm.expect(pm.environment.has('client_secret')).to.be.true;
pm.expect(pm.environment.has('username')).to.be.true;
pm.expect(pm.environment.has('password')).to.be.true;

var options = { 
  url: 'http://' + pm.environment.get("host") + '/api/oauth/token',
  method: 'POST',
  header: { 
Authorization: 'Basic '+btoa(pm.environment.get("client_id")+':'+pm.environment.get("client_secret")),
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
  },
  body: {
  mode: "urlencoded",
  urlencoded: [
      {key: "grant_type", value: "password", disabled: false},
      {key: "username", value: pm.environment.get('username'), disabled: false},
      {key: "password", value:  pm.environment.get('password'), disabled: false}
    ]
  }
};

pm.sendRequest(options, function(err, response) {
  pm.environment.set("oauth_token", response.json().access_token)
});

This pre-request works perfectly and stores the oauth_token in the proper variable

0
votes

Based on your sample code, I believe you have mis-typed 'headers'. It should work if you change it to 'header'.