Reputation: 776
This is the way I add headers to an http-request in my Angular 4 application:
constructor(private http: Http) { }
getUsers() {
const headers = new Headers(
{
'Content-Type': 'application/json',
'Authorization': 'somekey ' + localStorage.getItem('token')
});
return this.http.get(environment.apiUrl + 'users/all', {headers: headers})
}
My API works fine when I call it via Postman. And when I check the result of
request.getHeader("Authorization")
it returns back the proper value which is my token.
But when I call the API via frontend application
request.getHeader("Authorization")
returns null. And also creates a header named "access-control-request-headers" with this value: "authorization,content-type". Where is the token I set then? And why this request is not authorized to get the result just like when I call the API using Postman?
Upvotes: 1
Views: 2606
Reputation: 776
It was a CORS (Cross-Origin Resource Sharing) problem causing by the browser's mechanism. And I believe it's not a matter of frontend framework.
There are two different types of requests: Simple Requests and Preflighted Requests.
When you add new headers to a request, it won't be counted as a simple request anymore. And Unlike “simple requests”, "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this, since they may have implications to user data.
Like the simple requests, the browser adds the Origin header to every request, including the preflight. The preflight request is made as an HTTP OPTIONS request. It also contains a few additional headers and "Access-Control-Request-Headers" is one of those additional headers which is a comma-delimited list of non-simple headers that are included in the request. In my case the value of this header is: "authorization,content-type".
So, the request I was inspecting was the preflighted one not the actual-request I was sending to the backend-API.
You may deal with this preflighted request in your own way. Just like avoid filtering and set status 200 when http method is OPTIONS:
if("options".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
Which might not be the best solution but you won't get "Response for preflight has invalid HTTP status code 401".
Please let me know what is your preferred way to deal with this preflighted request
Here are the links I used to shape this answer. They can help you to learn more about CORS:
https://www.html5rocks.com/en/tutorials/cors/
http://restlet.com/company/blog/2015/12/15/understanding-and-using-cors/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Response for preflight has invalid HTTP status code 401 - Spring
Upvotes: 1
Reputation: 612
Try doing this.
private headers: Headers;
constructor(private http: Http) {
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Authorization', 'somekey ' + localStorage.getItem('token'));
}
public getUsers() {
const options = new RequestOptions({
headers: this.headers
});
return this.http.get(environment.apiUrl + 'users/all', options)
}
Upvotes: 2