How to get Header Location value from a Fetch request in browser - http-headers

From a ReactJS - Redux front app, I try to get the Location Header value of an REST API response.
When I Curl this :
curl -i -X POST -H "Authorization: Bearer MYTOKEN" https://url.company.com/api/v1.0/tasks/
I Have this answer :
HTTP/1.1 202 ACCEPTED
Server: nginx
Date: Fri, 12 Aug 2016 15:55:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Location: https://url.company.com/api/v1.0/tasks/status/idstatus
When I make a Fetch in ReactJS
var url = 'https://url.company.com/api/v1.0/tasks/'
fetch(url, {
method: 'post',
credentials: 'omit',
headers: {
'Authorization': `Bearer ${token}`
}
}
)
I don't have any Headers in the response object :
No header in Fetch request
I tried all the response.headers functions I've found in https://developer.mozilla.org/en-US/docs/Web/API/Headers :
response.headers.get('Location');
But well, as headers is empty, I have empty results.
Do you know why I can't get a proper Header object filled with the headers values ?

Thanks to John, I've found the answer.
I just had to put
Access-Control-Expose-Headers: Location
To my response headers and it worked, so now I can access Location value with :
response.headers.get('Location');
Thx John !

Besides to expose the Location Header in the server.
I just could access the location in the react application with:
response.headers.location;

Related

Why does this REST request work from every client except Talend API tester

This is an example of a REST POST request that works everywhere except Talend API tester. It give a 500 error.
Here is how I set the request up in my applications.
URLConnection connection = new URL("https://" + authHost + "/connect/token").openConnection();
logger.info("Connection oppened");
// message contains the form data: key=value&key=value&key=value
String message = "password=" + password + "&grant_type=password&username=" + username +
"&client_id=foolid&scope=mouthwash";
logger.info(message);
// Setting header fields.
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/json");
connection.getOutputStream().write(message.getBytes("UTF-8"));
Here is a working example in Postman
POST /connect/token HTTP/1.1
Host: identityserver.uat.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Cookie: ARRAffinity=6a37d2ecf3441e27913cb832c4b767c68cad0e45c8806b3c5344d1b52d57f67a; ARRAffinitySameSite=6a37d2ecf3441e27913cb832c4b767c68cad0e45c8806b3c5344d1b52d57f67a
Content-Length: 137
password=secret&grant_type=password&username=fool&client_id=foolid&scope=mouthwash
And here is what Talend say it sends, which gets the 500 error -- which I understand comes from the server.
POST /connect/token HTTP/1.1
Accept: application/json
Content-Length: 137
Content-Type: application/x-www-form-urlencoded
Host: identityserver.uat.example.com
password=secret&grant_type=password&username=fool&client_id=foolid&scope=mouthwash
What's happening here?

Get shopify analytics token programmatically

How do you get the token needed to make a request to the Shopify analytics API?
For example:
POST https://analytics.shopify.com/queries?beta=true
REQUEST BODY:
token: HOW_DO_I_GET_THIS?
q[]: SHOW+total_visitors+AS+%22total_visitors...
source: shopify-reports
I've tried using OAuth, but it seems to be a different token entirely.
You have to request Shopify Core GraphQL to get analyticsToken.
POST /admin/internal/web/graphql/core HTTP/1.1
Host: [[STORE_NAME]].myshopify.com
Accept: application/json
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
content-type: application/json
X-CSRF-Token: [[CSRF_TOKEN]]
Origin: https://[[STORE_NAME]].myshopify.com
Connection: close
Cookie: [[COOKIE]]
{ "query": "{ shop { analyticsToken } }" }
Since the request requires CSRF Token & Cookie, it's not programmatic at all.
For additional information please check the Examples for Testing in the Shopify Admin page.

Box api call returning 403 forbidden error in Vue but the same URL working in postman

I have a developer token for box and the box app all set up. when I use Postman I get the data that I am looking for returned. I have looked at the headers that Postman is sending and have provided the same in my code.
axios({
async: true,
crossDomain: true,
url: 'https://api.box.com/2.0/files/<File ID>/',
method: 'GET',
headers: {
'Postman-Token': '<Postman Token>',
'cache-control': 'no-cache',
Authorization: 'Bearer <Developer Token>',
Accept: '*/*',
},
}).then((res) => {
console.log(res);
}).catch(console.error);
This returns a 403 in the browser.
This is the Response Headers from Postman:
Date:"Wed, 03 Apr 2019 06:04:45 GMT"
Content-Type:"application/json"
Transfer-Encoding:"chunked"
Connection:"keep-alive"
Strict-Transport-Security:"max-age=31536000"
Cache-Control:"no-cache, no-store"
ETag:""0""
Content-Encoding:"gzip"
Vary:"Accept-Encoding"
BOX-REQUEST-ID:"<BOX-REQUEST-ID>"
Age:"0"
Response Headers from bowser
Access-Control-Allow-Origin: *
Age: 0
BOX-REQUEST-ID: <BOX-REQUEST-ID>
Cache-Control: no-cache, no-store
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Wed, 03 Apr 2019 06:36:01 GMT
Strict-Transport-Security: max-age=31536000
Transfer-Encoding: chunked
Vary: Origin,Accept-Encoding
Error in browser dev tools
GET https://api.box.com/2.0/files/<File ID>/ 403 (Forbidden)
Error: Request failed with status code 403
at createError (createError.js?2d83:16)
at settle (settle.js?467f:18)
at XMLHttpRequest.handleLoad (xhr.js?b50d:77)

Issue with set cookie headers from server and vue component vue-beautiful-chat

I have this issue on a Vue app, based on component vue-beautiful-chat: I make an http.post using http module via browser on localhost: when I check the response headers from the remote server, I see there are no "set-headers" with cookie values, only:
Content-Type application/json;charset=utf-8
If I send a post request via Node, Postman o cURL these are the response headers:
Connection keep-alive
Access-Control-Allow-Origin *
Set-Cookie JSESSIONID=wl6sCW6uT_9bAgoOSj9YtgfJvYGxF6XrNjH22YFm.srv79627; path=/
Server WildFly/10
Content-Type application/json;charset=utf-8
Content-Length 352
Date →Tue, 12 Mar 2019 22:33:25 GMT
In Vue app I receive
In the console developer I see in the tab application->cookies only one cookie saved on localhost.
Is this related to browser limitation? Any workaround?
I need to keep track of the value in set header from remote server for session management.
This is the actual code:
const options = {
hostname: 'XX.XX.XX',
port: 8080,
path: '/myurlsearch_2?searchText='+mess +'&user=&pwd=&ava=XXX',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Cookie': this.$session.exists('JSESSIONID=') ? this.$session.get('JSESSIONID=') :''
// 'Access-Control-Allow-Credentials:true' -> this won't work
}
Thanks in advance

How to correctly handle multiple Set-Cookie headers in Hyper?

I'm using Hyper to send HTTP requests, but when multiple cookies are included in the response, Hyper will combine them to one which then fails the parsing procedure.
For example, here's a simple PHP script
<?php
setcookie("hello", "world");
setcookie("foo", "bar");
Response using curl:
$ curl -sLD - http://local.example.com/test.php
HTTP/1.1 200 OK
Date: Sat, 24 Dec 2016 09:24:04 GMT
Server: Apache/2.4.25 (Unix) PHP/7.0.14
X-Powered-By: PHP/7.0.14
Set-Cookie: hello=world
Set-Cookie: foo=bar
Content-Length: 0
Content-Type: text/html; charset=UTF-8
However for the following Rust code:
let client = Client::new();
let response = client.get("http://local.example.com/test.php")
.send()
.unwrap();
println!("{:?}", response);
for header in response.headers.iter() {
println!("{}: {}", header.name(), header.value_string());
}
...the output will be:
Response { status: Ok, headers: Headers { Date: Sat, 24 Dec 2016 09:31:54 GMT, Server: Apache/2.4.25 (Unix) PHP/7.0.14, X-Powered-By: PHP/7.0.14, Set-Cookie: hello=worldfoo=bar, Content-Length: 0, Content-Type: text/html; charset=UTF-8, }, version: Http11, url: "http://local.example.com/test.php", status_raw: RawStatus(200, "OK"), message: Http11Message { is_proxied: false, method: None, stream: Wrapper { obj: Some(Reading(SizedReader(remaining=0))) } } }
Date: Sat, 24 Dec 2016 09:31:54 GMT
Server: Apache/2.4.25 (Unix) PHP/7.0.14
X-Powered-By: PHP/7.0.14
Set-Cookie: hello=worldfoo=bar
Content-Length: 0
Content-Type: text/html; charset=UTF-8
This seems to be really weird to me. I used Wireshark to capture the response and there're two Set-Cookie headers in it. I also checked the Hyper documentation but got no clue...
I noticed Hyper internally uses a VecMap<HeaderName, Item> to store the headers. So they concatenate the them to one? Then how should I divide them into individual cookies afterwards?
I think that Hyper prefers to keep the cookies together in order to make it easier do some extra stuff with them, like checking a cryptographic signature with CookieJar (cf. this implementation outline).
Another reason might be to keep the API simple. Headers in Hyper are indexed by type and you can only get a single instance of that type with Headers::get.
In Hyper, you'd usually access a header by using a corresponding type. In this case the type is SetCookie. For example:
if let Some (&SetCookie (ref cookies)) = response.headers.get() {
for cookie in cookies.iter() {
println! ("Got a cookie. Name: {}. Value: {}.", cookie.name, cookie.value);
}
}
Accessing the raw header value of Set-Cookie makes less sense, because then you'll have to reimplement a proper parsing of quotes and cookie attributes (cf. RFC 6265, 4.1).
P.S. Note that in Hyper 10 the cookie is no longer parsed, because the crate that was used for the parsing triggers the openssl dependency hell.