postman sendRequest use authorization from collection - postman

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.

Related

Postman access refresh_token?

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.

Postman - How to use pm.sendRequest without any cookies?

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?

Next.js not persisting cookies

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'),
},
});

How to add Cognito authorization to API request? So that Lambdas can access it

I want to add Cognito authorization to my API request so that the API Gateway can pass the information on to my Lambdas. I have read in other threads that I should add the id token as authorization header, so that is what I have tried so far.
I have tried the following:
fetch('api/public/libraries/sign-out-discourse', {
method: 'POST',
headers: new Headers([
// I get the idToken from CognitoUser.getSession => getIdToken()
['Authorization', idToken],
]),
})
I get the error message
{"message":"'Object]' not a valid key=value pair (missing equal-sign) in Authorization header: '[object Object]'."}
I have tried the following:
fetch('api/public/libraries/sign-out-discourse', {
method: 'POST',
headers: new Headers([
// I get the idToken from CognitoUser.getSession => getIdToken().getJwtToken()
['Authorization', jwtToken],
]),
})
I get the error message:
{"message":"Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=eyJraWQiOiJOemhFe..."}
What is the right way to pass authorization information to the api?
I think your solution may be a little too complex by utilizing the New Headers() method.
Try this:
fetch('api/public/libraries/sign-out-discourse', {
method: "POST",
headers: {
'Authorization': jwtToken
}
});

Fetch API with Cookie

I am trying out the new Fetch API but is having trouble with Cookies. Specifically, after a successful login, there is a Cookie header in future requests, but Fetch seems to ignore that headers, and all my requests made with Fetch is unauthorized.
Is it because Fetch is still not ready or Fetch does not work with Cookies?
I build my app with Webpack. I also use Fetch in React Native, which does not have the same issue.
Fetch does not use cookie by default. To enable cookie, do this:
fetch(url, {
credentials: "same-origin"
}).then(...).catch(...);
In addition to #Khanetor's answer, for those who are working with cross-origin requests: credentials: 'include'
Sample JSON fetch request:
fetch(url, {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
console.log('Gotcha');
}).catch((err) => {
console.log(err);
});
https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
Have just solved. Just two f. days of brutforce
For me the secret was in following:
I called POST /api/auth and see that cookies were successfully received.
Then calling GET /api/users/ with credentials: 'include' and got 401 unauth, because of no cookies were sent with the request.
The KEY is to set credentials: 'include' for the first /api/auth call too.
If you are reading this in 2019, credentials: "same-origin" is the default value.
fetch(url).then
Programmatically overwriting Cookie header in browser side won't work.
In fetch documentation, Note that some names are forbidden. is mentioned. And Cookie happens to be one of the forbidden header names, which cannot be modified programmatically. Take the following code for example:
Executed in the Chrome DevTools console of page https://httpbin.org/, Cookie: 'xxx=yyy' will be ignored, and the browser will always send the value of document.cookie as the cookie if there is one.
If executed on a different origin, no cookie is sent.
fetch('https://httpbin.org/cookies', {
headers: {
Cookie: 'xxx=yyy'
}
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));
P.S. You can create a sample cookie foo=bar by opening https://httpbin.org/cookies/set/foo/bar in the chrome browser.
See Forbidden header name for details.
Just adding to the correct answers here for .net webapi2 users.
If you are using cors because your client site is served from a different address as your webapi then you need to also include SupportsCredentials=true on the server side configuration.
// Access-Control-Allow-Origin
// https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
This works for me:
import Cookies from 'universal-cookie';
const cookies = new Cookies();
function headers(set_cookie=false) {
let headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}
Then build your call:
export function fetchTests(user_id) {
return function (dispatch) {
let data = {
method: 'POST',
credentials: 'same-origin',
mode: 'same-origin',
body: JSON.stringify({
user_id: user_id
}),
headers: headers(true)
};
return fetch('/api/v1/tests/listing/', data)
.then(response => response.json())
.then(json => dispatch(receiveTests(json)));
};
}
My issue was my cookie was set on a specific URL path (e.g., /auth), but I was fetching to a different path. I needed to set my cookie's path to /.
If it still doesn't work for you after fixing the credentials.
I also was using the :
credentials: "same-origin"
and it used to work, then it didn't anymore suddenly, after digging much I realized that I had change my website url to http://192.168.1.100 to test it in LAN, and that was the url which was being used to send the request, even though I was on http://localhost:3000.
So in conclusion, be sure that the domain of the page matches the domain of the fetch url.