8
votes

I am using spring security with angular 6. When i login using basic Auth server sends a cookie JessionID with response. I want to send this cookie with other request for authentication purpose but it gives me error Refused to set unsafe header 'Cookie' . When i hit the same endpoint from postman with same cookie in header it works.

Below is the method in angular:

Note: Currently i am manually adding it with headers.

private heroesUrl = 'http://localhost:8080/hi';
     header = new HttpHeaders().set("Cookie", "JSESSIONID=A2A75EC9A3E1172D60060C6E708549B5");
    getMessage() :Observable<Message>{
      return this.http.get<Message>(this.heroesUrl,{headers:this.header});
    }

Response which i get when i login using basic Auth

Response which i get when i login using basic Auth

2
I had the same problem but in a different scenario. You cannot set Cookie header manually with the request in your code. Also if the cookie is httponly, then it cannot be accessed by the code. However when I used postman to make a request, it worked. In my case, I evaded this issue by making my app on the same port as the server. The cookie gets sent automatically if the request comes from same origin.Abhishek Mehandiratta

2 Answers

13
votes

You can't do this, cause the browser doesn't allow you to do it. Let me describe the problem here:

Did you notice the Set-Cookie: JSESSIONID=......; Path=/; HttpOnly in your response headers? Well, The problem is the HttpOnly flag. Actually :) it's not a problem, it's a feature to prevent attacks that aim to steal your browser cookies:

HttpOnly is a flag added to cookies that tell the browser not to display the cookie through client-side scripts (document.cookie and others). ... When you set a cookie with the HttpOnly flag, it informs the browser that this special cookie should only be accessed by the server

So the browser doesn't allow any javascript code to access this variable. If you could change that value, then it's not a HttpOnly flagged cookie anymore:)

If you want to send this cookie via javascript, you should send it via the Authorization header for example and write middleware in Java server so that it captures these values from the Authorization header and think of them as JSESSIONID cookie. No more options for you :)

-1
votes

I also had this issue, and i just fixed it right now.

I realized that is you pass option {withCredentials: true} your browser will automatically send all available cookies along with your request. That way you don't have to add the cookies manually, so it's fluent and i thinks it also safer.

Change your code to this and see and check.

Cookies are available when the path is same as your front end.

private heroesUrl = 'http://localhost:8080/hi';
 
getMessage() :Observable<Message>{
  return this.http.get<Message>(this.heroesUrl, {withCredentials: true});
}