Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4.3 HttpClient doesn't send Authorization header

Tags:

cors

angular

I attempted to send a request with an authorization header using Angular's HttpClient but the header was not set successfully.

Here my code.

import {HttpClient, HttpHeaders} from '@angular/common/http';


constructor(private http: HttpClient,
            private auth: AuthService) {
}

sendRequest() {
  this.http.get(this.url, {
    headers: new HttpHeaders().set('Authorization', 'Bearer ' + this.auth.getAccessToken())
  }).subscribe(
    data => {
      console.log(data);
    },
    error => {
      console.log(error);
    }
  );
}

And here the network debug header source.

OPTIONS /userinfo HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Referer: http://localhost:4200/user
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.8,en;q=0.6

The response header is as follows.

HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sun, 27 Aug 2017 23:45:15 GMT
Content-Length: 18

Is there something wrong?

like image 571
dchiba Avatar asked Aug 27 '17 02:08

dchiba


1 Answers

If you look at the headers that you included in your question, you will see that this was an OPTIONS request. That indicates that you were attempting to make a cross-site request, and that the browser's CORS (Cross-Origin Resource Sharing) protocol kicked in.

You apparently made a GET request with credentials against a domain (or port number) that was different from the origin of the page making the request. And indeed, we see from your headers that the origin was port 4200 (the standard port for the angular dev server), and that the request was made to port 8080 (probably a java back-end?).

Standard CORS protocol is for the browser to do a "preflight" check, by sending the OPTIONS request to see if an Access-Control-Allow-Origin header comes back stating that the origin is allowed to access the destination.

If the header comes back ok, then the browser will make the GET request. If not, you will get a 401 response.

All of this is done by the browser, and is out of your control.

The spec (https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0) says that when the browser sends the OPTIONS request as part of the preflight, it must not include your authorization header - that will only be sent on the GET.

So, no - nothing is wrong here - it is working as expected.

Now, if after this, you get a 401 and the GET is never sent, then you'll have to modify the server to send the proper Access-Control-Allow-Origin header in response to the OPTIONS request.

For more info CORS, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

like image 93
GreyBeardedGeek Avatar answered Oct 27 '22 14:10

GreyBeardedGeek