"Cookie" header is never sent, even when browser console shows otherwise
I am trying to use request-promise and Reactjs to send request from my web application to SAP B1 Service Layer. First, I tried using the "headers" option in request-promise, then tried setting a cookie using rp.cookie("...") and jar.setCookie("...") but got errors both times.
The browser console is showing it is sending the "Cookie" header, but when I intercept the request using Burp Suite the header is never sent.
var rp = require('request-promise').defaults({jar:true});
var rd= require('request-debug');
rd(rp);
const b1jar=rp.jar();
let options = {
method: method,
rejectUnauthorized: false,
uri: url,
insecure:true,
jar:b1jar,
json: true,
resolveWithFullResponse:fullres,
// I TRIED TO USE THIS FIRST
headers:
{ 'Cookie': "B1SESSION="+(sessionStorage.SessionID||'')+';',
}
};
//THEN DELETED THE headers OPTION AND TRIED WITH THE jar OPTION
var b1cookie=rp.cookie('B1SESSION='+sessionStorage.SessionID);
b1cookie.setExpires(moment().add(sessionStorage.SessionTimeout,'m')
.toDate());
b1jar.setCookie(b1cookie,config.server);
res = await rp(options);
The expected result is that the B1SESSION Cookie should be sent when using rp(options), but it is not.
That API is pretty bad, try axios...
https://www.npmjs.com/package/react-axios
Related
I am trying to send a POST request with body that contains one key with file base64 content.
The problem is that I never get a response. When I check the "Network" tab in Dev Tools, I see that the request is stuck on "pending". When I console.log the variable that contains the base64, I see that it's just 256kb. It happens both with fetch or axios.
This is how I sent the request:
const response = await axios.post(
"/api/newroute",
{
fileName,
fileBase64
},
{
// maxContentLength: Infinity, // Tried that
// maxBodyLength: Infinity, // Tried that
}
);
console.log(response); // never happens
I am not sure whether it is a backend issue or a frontend one (this is a route from next.js).
I also tried to send it as FormData but that didn't help.
Do you have any idea what could have caused this?
Trying to call the below API by using axios.getmethod. I've bypassed the CORS by using the Moesif CORS google extension.
The API required the tokens in order to pull the result by using POSTMAN.
Insert the valid tokens: Getting the CORS error although the CORS extension is enabled.
CORS Error
Without the tokens: Getting the 401 Unauthorized with CORS extension enabled as well.
401 Unauthorized
I'm sort of confused, is it either my token unauthorized issue or the CORS issue here? could someone please advise? However, if I called the other API that does not require the token I'm able to get the result without any issue with the CORS extension enabled.
Sharing my example codes here:
const tokenStr = 'abc1234'; // example
const config = {
headers: { Authorization: `Bearer ${tokenStr}` }
};
let dcqoapi =
"http://quote.dellsvc/v3/quotes?number=" + Quote + "&version=" + Version;
const calldcqoapi = () => { //assign a variable for a call function
Axios.get (dcqoapi,config).then(
(response) => {
console.log(response);
})
};
You need to trace HTTP responses more scientifically - using browser tools or a tool such as Charles proxy. Bear in mind that APIs are sometimes poorly implememted and don't return CORS headers correctly.
For an approach, see Step 15 of my blog post. Do you get response headers to that work for the browser in all of these cases?
Call API without an access token
Call API with an invalid access token
Call API with a valid access token
The issue was resolved via disabling the web security from Chrome. Here are the below actions I've taken: [WORKS FOR LOCALHOST]
Create a shortcut on your desktop.
Right-click on the shortcut and click Properties.
Edit the Target property.
Set it to "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:/ChromeDevSession"
Open Google chrome (You should see the message "disable-web-security" on top of the page)
Run your app
Copy your localhost URL and paste it to the Chrome
It works perfectly now for calling the API with headers tokens.
By doing the above steps, we had fully bypassed all the security including the CORS. Hence, Moesift CORS is no longer required.
As I'm using POSTMAN for calling the API with the Headers.
Some little changes from my codes, instead of putting 'Bearer' and I've removed it.
The 'bearer' is for authorization.
Headers are not considering bearer tokens, it's just a key so we shouldn't enter the 'bearer' for the POSTMAN headers.
let config = {
headers: { Authorization: 'PlACE YOUR TOKENS HERE'}
};
let dcqoapi =
"https://quote.dellsvc/v3/quotes?number="+ Quote +"&version=" + Version // set DCQO API
const calldcqoapi = () => { //assign a variable for a call function
Axios.get (dcqoapi,config).then(
(response) => {
console.log(response);
})
};
I am using Leaflet in my Angular.js map application. One of my resources requires an authorization header with token. I am using the leaflet-realtime plugin (found here: https://github.com/perliedman/leaflet-realtime) to get map updates and therefore need to be able to specify my header when realtime performs a fetch to get the data.
I first tried using another library, fetch-intercept (found here: https://github.com/werk85/fetch-intercept), to intercept the requests and attach the header, but the interceptor was being ignored. I included a console.log in the interceptor and it was never reached.
After more research, I noticed specifying headers is supposed to be supported: https://github.com/perliedman/leaflet-realtime/pull/83. However, I cannot find an example for how to properly attach an authorization token. Here is what I am currently trying:
this.mapRealtime = L.realtime({
url: this.getRealtimeUrl(),
crossOrigin: true,
headers: {"Authorization": "token"},
type: 'json',
},
However, when I check the Network logging from my web browser (Chrome) debugging console, all I see for the Request Headers is:
Provisional headers are shown
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
and the server returns status 403 with errortype MissingAuthenticationTokenException.
Can anyone provide an example of how to correctly attach the token? Thanks!
The realtime Leaflet only take url or json file path and you will be unable to pass headers(auth) as they have patch for it which is not working. I was facing same issue. What I did is following:
realtime = (L as any).realtime(async function (success, error) {
let geodataJson = await self.updateGeoJson();
success(geodataJson);
}, {
interval: 15 * 1000,
onEachFeature: onEachFeature,......
I have pass funtion to realtime and in that function I called simple API with headers
async updateGeoJson() {
await this.api.getMarkersGeoJson().subscribe((res: any) => {
this.geoData = res;
});
return this.geoData; }
On first call it will not get data in from this function so we also need to load data in this.geoData in ngOnInit before initmap.
For me it is working I know this is just work around but this issue is still in leaflet realtime. Hopefully this will work for you
why I use axios.delete(url) or axios.put() to send request, but when I check request from NetWork in Chrome Dev Tools the Request Method is OPTIONS and Access-Control-Request-Method is DELETE or PUT like this:
DELETE or PUT (or other non-simple) requests first send out a preflighted OPTIONS request to determine if you're allowed to send this request. The request method is given in the Access-Control-Request-Method header.
See more here https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
Axios uses JSON as the default content type, the call was always going with a browser as a OPTIONS call not a POST method. To overcome, we need to set the ‘Content-Type’ correctly. My configuration as following
let config={
headers: {'Content-Type' : 'application/x-www-form-urlencoded'}
}
return axios.post(postUrl,postJson,config).then(response=>{
return response.data;
}).catch(error=>{
return error;
});
I am generating in server side a pre-signed URL request with the following parameters for GeneratePresignedUrlRequest : bucket, key, expiration = in 1 hour and method = PUT.
In my Angular app, I am uploading the file using ng-file-upload
Upload.http({
url: $scope.signedUrl,
method: "PUT",
headers : {
'Content-Type': $scope.file.type
},
data: $scope.file
});
The problem is that I always have a 403 response unless I set the type of the file in GeneratePresignedUrlRequest.contentType.
The problem is that I can't predict in advance what type of file the user will choose (image/png, image/jpeg, text/plain...).
How can I generate a pre-signed url that accept all kinds of content-type ? I tried setting it to null, it keeps sending 403 errors.
Thanks.
I just ran into this problem, and just got it working. Replace your Upload.http code with the following:
var reader = new FileReader();
var xhr = new XMLHttpRequest();
xhr.open("PUT", $scope.signedUrl);
reader.onload = function(evt) {
xhr.send(evt.target.result);
};
reader.readAsArrayBuffer($scope.file);
The problem ends up being that S3 is looking for a specific Content-Type (binary/octet-stream), which it infers when you omit the Content-Type header.
The value from the Content-Type header is a mandatory component of the signature. It isn't possible to pre-sign a PUT URL without knowing the value that will be sent.
A POST upload is more flexible, since you can allow any Content-Type in the signed policy.
One possible solution might be if you keep track of the extension?
eg: ends with ".jpg" -> content type = "image/jpeg", end with ".zip" -> content type = "application/octet-stream".
Ref: get the filename of a fileupload in a document through javascript