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
Related
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.
I have a API call that takes a POST body of
raw: {"category":1, "fmipstatus":true} and it is of type JSON.
Content-Type is application/json
I use Postman to send this API call and I get a 200 response code.
I want to code this call as part of a Postman Pre-request Script
I have the following:
method: 'POST',
header: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Basic NDc0OmVmMzAwZThkNGFjNTQ2ZjU3ZjhjYWQ5ZWQwMjUyNGIxYTI5NmQwM2M='
},
body: {
mode: 'raw',
raw: JSON.stringify( {category: 1, fmipstatus: false} )
}
I always a 401. In the first API through Postman, if I put garbage in there, I also get a 401 response code.
So I am thinking somehow in my Postman script, the body is defined incorrectly.
Does anyone the error?
401 is an authorization error. Something is wrong with your Auth token, either its expired, incorrect, or you're passing it incorrectly.
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?
I am trying to test the /login API via POSTMAN (via FE it works fine) but it doesn't
show anything in the body part even though I am sending body data.
but when printing the request from the BE, the body is empty...
....
body: {},
....
unlike when using FE:
....
body: {data: { username: 'admin', password: 'admin' }},
....
Any idea what's going on? If anything else is needed to be provided - pls let me know
I know it's going through because the server responds with 500 and the message
TypeError: Cannot read property 'username' of undefined
The weird part is, that the data I am sending, are nowhere to be found in the request object at all :(
EDIT:
This is how I call it from the FE:
return axios.post('login', { data: user })
and the user is:
user: {
username: 'admin',
password: 'admin'
}
So the format should be right
data: {
username: 'admin',
password: 'admin'
}
Because that's how I access it on the BE side
req.body.data.username
EDIT2:
The ultra-super-rare-weird part is, that JEST is working fine :)
const creds = {
data: {
username: 'admin',
password: 'admin'
}
}
return request(app)
.post("/api/v1/login")
.send(creds)
.expect(200)
.then(res => {
expect(res.body).toMatchSnapshot()
})
and this test passes .... f**k me guys.. what's going on?
if you are working with an express server try to parse your body in the server as soon as you initialize express app before routing
const app = express();
app.use(express.json());
The syntax of your body looks like JSON, yet you've specified the type of the body as "raw text". This will set the Content-type header of your request to "text/plain", which is probably causing your backend to be unable to actually read the body (because it expects a JSON object).
Simply switch from "Text" to "JSON", wrap your current body in curly braces (so that you're actually sending a single JSON object with a data property set) and try sending the request again. The content-type header will be correctly set to "application/json" this time and your backend will read the data successfully.
Add the following parameters in the request headers configuration in Postman:
Content-Type: application/json
Content-Length
The value of Content-Length is automatically calculated by Postman when a request is sent. Both values are used to identify the media type of the request body and to parse it accurately. When missing, the body may be ignored completely (depending on the server).
React Client Code - Using request promises to send username and password in Header
var password = values.password;
var email = values.email;
request
.head(
"https://us-central1-simplineet-754e8.cloudfunctions.net/CreateUserAuth"
)
.set('Content-Type', 'application/x-www-form-urlencoded')
.auth(email, password, false)
.query(dataobj)
.then(res => {
console.log(res);
if (res.statusCode === 200) {
console.log("statusText",res.body);
} else {
console.log("statusText",res.statusText);
}
})
.catch(err => {});
Backend - Google Cloud Function to Handle Basic Auth Requests from Client
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({origin: true}));
exports.CreateUserAuth = functions.https.onRequest((request, response) => {
var corsFn = cors();
corsFn(request, response, function () {
// Request Header
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
response.setHeader('Access-Control-Allow-Credentials', true);
response.setHeader('Access-Control-Allow-Origin', '*');
var auth = require('basic-auth') // basic-auth NPM package to extract username and password from header
var user = auth(request)
var email = user.name; // Getting username from Auth
var password = user.pass; // Getting password from Auth
var username = request.query.username;
response.send('Hello from Firebase!'); // Not getting this response in Client
});
});
Response Getting in Client :
Response {req: Request, xhr: XMLHttpRequest, text: null, statusText: "", statusCode: 200, …}
As per MDN docs, HEAD responses should not have a body:
The HTTP HEAD method requests the headers that are returned if the specified resource would be requested with an HTTP GET method. Such a request can be done before deciding to download a large resource to save bandwidth, for example.
A response to a HEAD method should not have a body. If so, it must be ignored. Even so, entity headers describing the content of the body, like Content-Length may be included in the response. They don't relate to the body of the HEAD response, which should be empty, but to the body of similar request using the GET method would have returned as a response.
My guess is that GCP is handling it as a GET and stripping out the body before returning a response.
However, keep in mind that Google Cloud Functions HTTP trigger docs don't explicitly say that HEAD is a supported method:
You can invoke Cloud Functions with an HTTP request using the POST, PUT, GET, DELETE, and OPTIONS HTTP methods.
It looks like you are making a HEAD request instead of a POST request. Change to request.post() and it should work