When calling my REST Service in Angular, there are no response headers.
Login method in Angular
login(username: string, password: string) {
const credentials = { "username": username, "password": password };
return this.http.post(this.url, credentials)
.subscribe(
data => console.log(data), // JSON.stringify(data.headers) also is empty
error => console.log(error)
);
}
Output in the Chrome dev tools console
Response {_body: "", status: 200, ok: true, statusText: "OK", headers: Headers…}headers: Headers_headers: Map(0)_normalizedNames: Map(0)proto: Objectok: truestatus: 200statusText: "OK"type: 2url: "http://localhost:8080/backend/rest/login"_body: ""proto: Body
But when I send the same post request with postman, I get the expected result:
Access-Control-Allow-Credentials →true
Access-Control-Allow-Origin →chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Authorization →Bearer eyJ[...]
Connection →keep-alive
Content-Length →0
Date →Mon, 12 Jun 2017 13:19:54 GMT
Server →WildFly/10
Vary →Origin
X-Powered-By →Undertow/1
The REST Service
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(CredentialsDTO credentialsDTO) {
try {
authService.login(credentialsDTO.getUsername(), credentialsDTO.getPassword());
} catch (WrongCredentialsException e) {
return Response.status(Status.FORBIDDEN).entity("WrongCredentialsException").build();
}
// Issue token
String token = issueToken(credentialsDTO.getUsername());
// Return the token on the response
return Response.ok().header(AUTHORIZATION, "Bearer " + token).build();
}
Why can't I see the headers in chrome ?
UPDATE I am also using a CORSFilter that allowed Javascript to contact my backend in the first place. This is how it is configured in my web.xml
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- CORS Filter mapping -->
<filter-name>CORS</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
Although I thought it was configured to allow everything, I am not sure if this is related to my problem.
By default CORS responses only exposes these 6 headers to scripts:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
To allow scripts to access other headers sent by the sever, the server needs to send the Access-Control-Expose-Headers
Header.
The Access-Control-Expose-Headers response header indicates which headers can be exposed to scripts as part of the response by listing their names.
eg: Access-Control-Expose-Headers: Authorization, X-Foobar
You can tweak your web.xml
file including this to allow the Authorization
header to be accessed from the script that made the XHR:
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Authorization</param-value>
<init-param>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With