Hi @allenheltondev I read your Article which is something I’ve wanted for a while - one thing I’m unsure of, is, where to put my client_id and client_secret, it looks like they go in the variable Basic_Auth but as it’s multiple values I don’t know how to do it - could you show me how it should be done please - it will be really good to get this working - thanks for a great article
Hey @pkfox
Welcome to the Postman community!
Might be good to tag @allenheltondev in the message so that he can see the love and the question.
Failing that, you could reach out to him here too:
Thanks Danny but I don’t do the social media stuff
I reached out to Allen to make him aware of your message.
Thanks @danny-dainton for the ping.
Hey @pkfox, basic auth is a base64 encoded version of your client id and secret. You can create the value by hand by base64 encoding <client id>:<client secret>
or you can use a website that does it for you, like this one.
Thanks Allen, do I populate the Postman Basic_Auth variable like this client_id:abase64encodedvalue , client_secret:anotherbase64encodedvalue
do i need to separate the values with commas
Thanks @danny-dainton
These logs might help
POST https://login.microsoftonline.com/: {
“Request Headers”: {
“accept”: “application/json”,
“content-type”: “application/x-www-form-urlencoded”,
“authorization”: “Y2xpZW50X2lkOjo0MWVlZWJiZC1lYTdmLTRmNDktYTkzNi0xNjI0YjZjYjljNzI= Y2xpZW50X2lkOjpVSUM4UX5uajNjRGV0UjRYUWxTTmJtMTlXcHl3d2VKTWkuQ3V3YkdB”,
“user-agent”: “PostmanRuntime/7.36.3”,
“postman-token”: “0afdda48-5d53-42b3-a6b6-83b0c5016773”,
“host”: “login.microsoftonline.com”,
“accept-encoding”: “gzip, deflate, br”,
“connection”: “keep-alive”
}
}
‘Unable to load access token from response’
GET http://nuc:9653/wordle/getwordleanswers: {
“Network”: {
“addresses”: {
“local”: {
“address”: “10.10.1.8”,
“family”: “IPv4”,
“port”: 54770
},
“remote”: {
“address”: “10.10.1.5”,
“family”: “IPv4”,
“port”: 9653
}
}
},
“Request Headers”: {
“authorization”: “Bearer”,
“user-agent”: “PostmanRuntime/7.36.3”,
“accept”: “/”,
“postman-token”: “e971df37-4c61-4c9e-9b0a-33ad963e3dc6”,
“host”: “nuc:9653”,
“accept-encoding”: “gzip, deflate, br”,
“connection”: “keep-alive”
},
“Request Body”: “”,
“Response Headers”: {
“content-length”: “0”,
“date”: “Wed, 14 Feb 2024 09:34:36 GMT”,
“server”: “Kestrel”,
“www-authenticate”: “Bearer error="invalid_token"”
}
}
Here is an example of authenticating to Microsoft using a pre-request script.
Slightly different to Alan’s example but same concept.
The only thing you will really need to change is the grant type in the body.
let currentDateTime = Date.now();
let tokenExpiry = pm.environment.get("bearerTokenExpiresOn")
// console.log("currentDateTime: " + currentDateTime);
// console.log("tokenExpiry: " + tokenExpiry);
if (!pm.environment.get("bearerToken") || currentDateTime > tokenExpiry) {
pm.test("Pre-request check for Environment Variables", function () {
let vars = ['clientId', 'clientSecret', 'tenantId', 'username', 'password', 'scope'];
vars.forEach(function (item) {
// console.log(item);
pm.expect(pm.environment.get(item), item + " variable not set").to.not.be.undefined;
pm.expect(pm.environment.get(item), item + " variable not set").to.not.be.empty;
});
pm.sendRequest({
url: 'https://login.microsoftonline.com/' + pm.environment.get("tenantId") + '/oauth2/v2.0/token',
method: 'POST',
header: 'Content-Type: application/x-www-form-urlencoded',
body: {
mode: 'urlencoded',
urlencoded: [
{ key: "client_id", value: pm.environment.get("clientId"), disabled: false },
{ key: "scope", value: pm.environment.get("scope"), disabled: false },
{ key: "username", value: pm.environment.get("username"), disabled: false },
{ key: "password", value: pm.environment.get("password"), disabled: false },
{ key: "client_secret", value: pm.environment.get("clientSecret"), disabled: false },
{ key: "grant_type", value: "password", disabled: false },
]
}
}, function (err, res) {
if (err) {
console.log(err);
} else {
pm.test("Pre-request Microsoft login Status code is 200", () => {
pm.expect(res).to.have.status(200);
let resJson = res.json();
// console.log(resJson);
pm.environment.set("bearerToken", resJson.id_token);
pm.environment.set("bearerTokenExpiresOn", Date.now() + resJson.expires_in * 1000);
// console.log("bearerTokenExpiresOn: " + pm.environment.get("bearerTokenExpiresOn"));
});
}
});
});
};
You then just set the auth as following.
Thank you Mike I’ll give it a shot
Hi Mike what do I need to put in the scope var ?
Between yours and Allens code I’ve come up with this and it works !!! thanks to you both
pm.sendRequest({
url: pm.environment.get('AzureURL') + pm.environment.get('TenantId') + '/oauth2/v2.0/token',
method: 'POST',
header: 'Content-Type: application/x-www-form-urlencoded',
body: {
mode: 'urlencoded',
urlencoded: [
{ key: "scope", value: pm.environment.get('Scope')},
{ key: "client_id", value: pm.environment.get('ClientId')},
{ key: "client_secret", value: pm.environment.get('ClientSecret')},
{ key: "grant_type", value: "client_credentials"}
]
}},
function (err, res) {
if (err) {
console.log('We have an error ',err);
} else
{
pm.environment.set('BearerToken', res.json().access_token);
}});
Glad you got it working.
In relation to scope, this will be down to the particular application you are trying to authenticate against.
Have a look at the Microsoft docs in relation to the particular grant type as it does explain the flows quite well, and includes code examples.
For example.
In my instance, we were using Azure Websites as a wrapper and the scope is set to “openid profile email”.
You might want to consider extending your code, and including the expiry date\time.
For Microsoft, I don’t think it really matters as the tokens last for an hour, and it doesn’t really matter if you get a new token each time you run your collection. There isn’t a limit as far as I’m aware. It might be different if you use another authentication provider, so its just useful knowing that you can conditionally check the existing token and only get a new token if needed.
I would also recommend having a test in there somewhere, so it only tries to set the bearer token if the access token exists. Otherwise if it doesn’t exist, you will just get a fatal error which isn’t much use when troubleshooting.
I hear ya Mike but this will only be used to test my self hosted API at home, it’s waaay better than jumping to the Linux cli and cutting and pasting from a bash script - thanks again.
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.