I configured Postman to use the authorization code flow. Problem is our tokens expiry pretty fast and I need to re-run the flow every time it expires. So I was thinking to implement a refresh_token flow in the pre-requests script (unless there is a Postman-native way to do it).
Now my question is where can I find the refresh_token? Is there any way to access it or is it 'thrown away' and only the access_token is used?
Add the following code to the Collection Pre-request Script. (Edit it to your own url and body.)
// Set refresh and access tokens
const loginRequest = {
url: pm.environment.get("mainUrl") + "/authenticate/login", //The url that the token returns
method: 'POST',
header: {
'content-type': 'application/json',
'Accept': "*/*"
},
body: {
mode: 'raw',
raw: JSON.stringify({ //Your body
"username": pm.environment.get("username"),
"password": pm.environment.get("password")
})
}
};
pm.sendRequest(loginRequest, function (err, res) {
pm.environment.set("accessToken", res.json().accessToken); //The token returned in the response and the environment value to which the value will be sent
pm.environment.set("refreshToken", res.json().refreshToken);
});
This request runs before every request.
Finally, In the "Token" field in the "Authorization" tab of the requests, call the accessToken value from the environments.
{{accessToken}}
Each time the request runs, it will refresh the token value and use this value.
Related
In my Postman collection, I have a pre-request script that ensures I have a valid JWT token available for authentication. It looks similar to the following (I have removed the logic of checking expiration and only fetching a new token if needed):
function get_and_set_jwt() {
let base_url = pm.environment.get("BASE_URL")
pm.sendRequest({
url: base_url + '/api/auth/',
method: 'POST',
header: {
'content-type': 'application/json',
'cookie': ''
},
body: {
mode: 'raw',
raw: JSON.stringify({ email: pm.environment.get("USER_EMAIL_ADDRESS"), password: pm.environment.get("USER_PASSWORD") })
}
}, function (err, res) {
let jwt = res.json().token
postman.setEnvironmentVariable("JWT", jwt)
});
}
get_and_set_jwt();
I am attempting to set 'cookie': '' so that the request from this script will be made with no cookies. The backend I am working with sets a session cookie in addition to returning the JWT, but I want to force all future requests (when I need to renew the JWT) to not include that session information.
Unfortunately, if I check the Postman console, I see that the requests are still being sent with the cookie header, and the session cookie that was set by the earlier response. I have even tried overriding it by setting 'cookie': 'sessionid=""', but that just yields a request that includes two session ids in the cookie header (it looks like sessionid=""; sessionid=fasdflkjawew123sdf123;)
How can I send a request with pm.sendRequest with either a completely blank cookie header, or without the header at all?
This is my code in vue,
resetPOST(){
var formData = new FormData();
formData.append('old_password', this.oldPassword);
formData.append('new_password1', this.password1);
formData.append('new_password2', this.password2);
axios.post('http://localhost:8000/rest-auth/password/change/',
{headers: { 'Authorization' : this.token },
data: {
old_password: this.oldPassword,
new_password1: this.password1,
new_password2: this.password2
}
})
},
where the variable 'token' has a value like that : bbf957d27925a860f8c678546cf0425dbf7ddf98
I do not understand why I get this error, if I try the back part I enter the old password, and the two new passwords and it works. For some reason I it isn't taking the token parameter.
Thanks in advance
You are missing the Bearer. Most of the frameworks by default require you to send the authorization in the following format: Bearer <token>.
If you changed the Bearer word to another you should use that one but if you left it to as default in django-rest-auth you have to use the following:
axios.post('http://localhost:8000/rest-auth/password/change/',
{headers: { 'Authorization' : `Bearer ${this.token}` },
data: {
old_password: this.oldPassword,
new_password1: this.password1,
new_password2: this.password2
}
})
I had a similar issue. I realized I was using the same axios instance for users logged into the app which meant using an authentication token. Of course if you are resetting your password you do not have authentication (and therefore a token). Use a different axios instance for your reset password like this:
const instance = axios.create({
baseURL: Store.state.endpoints.baseUrl,
headers: {
'Content-Type': 'application/json'
},
// xhrFields: {
// withCredentials: true
// },
xsrfCookieName:"csrftoken",
xsrfHeaderName:'X-CSRFToken'
})
return instance;
}
Notice there is no auth token and credential are commented out (could probably set to false too). This worked for me.
I can send a request in a Postman pre-request script as seen below. What I would like to do is use the same authentication as is set in the Collection so that if the Collection changes then my sendRequest follows suite.
pm.sendRequest({
url: 'http://some_url',
method: 'GET',
header: {
'content-type': 'application/json',
'authorization': 'Basic ' + auth
},
}, function (err, res) {
// do something
});
The reason I want to do this is that I want to share the collection with partners and customers and each of them may use a different authentication type. At the moment I have configured my collection to use basic authentication and have used variables for user name and password. If, for example, a partner switches the collection to use OAuth then they will need to also update all of my pre-request scripts to use OAuth.
If pm.sendRequest() was able to inherit the authentication just as each request in the collection can then the partner could make the change in one place.
This will work, assuming you're executing sendRequest after a request which had an authorization header as well:
pm.sendRequest({
url: 'http://some_url',
method: 'GET',
header: {
'content-type': 'application/json',
'authorization': request.headers["authorization"]
},
}, function (err, res) {
// do something
});
Information on the Request object can be found here.
I have a server-side rendered Next.js/express app that communicates with a Django API (cross-origin). I login a user like so:
const response = await fetch('localhost:8000/sign-in', {
method: 'POST',
credentials: 'include',
body: JSON.stringify({ email, password }),
headers: { 'Content-Type': 'application/json' },
});
const result = await response.json();
if (response.status === 200) {
Router.push('/account');
}
Django successfully logs in the user and returns set-cookie headers for the csrftoken and sessionid cookies, however, when I navigate to a different page (like in the above code when I Router.push), the cookies don't persist.
I assume this has something to do with server-side vs. client-side, but when cookies are set in the browser I expect them to persist regardless.
How can I get these cookies, once set, to persist across all pages on the client side?
It turns out that set-cookie is the old way of doing things. It's controlled by the browser, so it's obfuscated.
I ended up sending the csrftoken and sessionid back to the client in the JSON body, and saving them to localStorage using localStorage.setItem('sessionid', 'theSessionId') and localStorage.setItem('csrftoken', 'theCsrftoken').
Then when I need to make an authenticated request, I include them in the fetch headers:
const response = await fetch(`${API_HOST}/logout`, {
method: 'POST',
headers: {
'X-CSRFToken': localStorage.getItem('csrftoken'),
sessionid: localStorage.getItem('sessionid'),
},
});
I have a request were the exact response from one request is the body of another request.
Is there an easy way to store the response from one request to reuse as the body of another request in Postman?
I tried storing the response body in a global variable customerData and then having the body of my other request be {{customerData}} but this does not work.
Thanks for the help.
You could achieve this by using the sendRequest() function in the Tests tab of your first GET request. This will send the request and get the data once this has completed, it will then POST that same response data to another endpoint.
This is a very basic example that can be added to the Tests tab, this can be changed/adapted to your own context:
pm.sendRequest({
url: 'localhost:3000/post',
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: {
mode: 'raw',
raw: JSON.stringify(pm.response.json())
}
}, (err, res) => {
console.log(res)
})
This is what it looks like in Postman - I've sent a basic request to the /get route and in the Tests tab, I'm using that response data as the payload for the POST request by inserting the pm.response.json(). You can see the request body for the /post route has been taken from the first request.
API-1 - Test Tab
//Get the response of first API
var jsonData=JSON.parse(responseBody);
//Convert the JSON response to String
var jsonString=JSON.stringify(jsonData);
//Store in environment variable
pm.environment.set("MyPayLoad", jsonString);
API-2 - Body
{{MyPayLoad}}
This way response from API-1 is passed as payload to API-2