Get a "Response header" Cookie from angular $http POST request - angularjs

I'm writing a small app using angular.
I need to access a couch database. I only have a user in that DB.
Using cURL commands I can request a session cookie to that database and that use that cookie to request a specific document.
When in angular code I use:
$http.post(url, data).then(...);
Where 'data' has username and password, I can see the cookie using chrome (like in this image chrome dev tool output), but in a code, I can't access it.
Can someone help me with this?

You can not access an HttpOnly cookie using script in browser due to security reasons. It can only be accessed on server.
If you need to include cookies in cross domain requests use withCredentials in the request. See $http docs

$http.post returns a response with a property:
headers – {function([headerName])} – Header getter function.
So you should be able to do something like
.then((response) => {
console.log(response.headers('set-cookie'));
});
See the documentation here

Try to use response.headers('set-cookie')
For the crossdomain situation, the server has to send
Access-Control-Expose-Headers: set-cookie header to make the custom headers visible.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Expose-Headers

Related

How to fix this Access-Control-Allow-Headers error

I'm using angularJS for POST from localhost to some API. but I got this error message:
XMLHttpRequest cannot load "...API link..." Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
I can post to the API when I use "Allow-Control-Allow-Origin" chrome extension. But this is just temporary, This way only works when I use this extension on my borwser. But my users got this problem when they use in their own browser.
How to fix this from client side.
I don't think you can fix this issue client side. The API server controls who can access what (using the Allow-Control-Allow-Origin header) so you have to change it there.
The CORS (Cross-Origin Resource Sharing) Request should be enabled in your server i mean in your api like header("Access-Control-Allow-Origin: *");
, otherwise if you still want to access the request from another domain (localhost) if api host is different , in your js code try to use jsonp
here is the documentation
https://docs.angularjs.org/api/ng/service/$http#jsonp

Angular (or something else) isn't saving JSESSIONID cookie

I'm setting up a simple authentication service for my angular website using Spring for my backend and I have a following problem.
When I send a cross domain get request with credentials (REST controller on backend), I get authorized by Spring Security, I get a JSESSION cookie and all is fine. What's not fine is that the cookie isn't saved and I can't access it in any way I could think of to save it manually.
Am I missing something here? If you need additional information, I'd be glad to provide it.
#Edit
I have Set-Cookie header in my response:
(...)
Server
WildFly/8
Set-Cookie
JSESSIONID=CODE; path=/PATH
(...)

AngularJS / Restangular sessions

Do I need to do anything special concerning sessions/authentication? My server can't see my session after I login via restangular post method. The login is successful, but no sessions are being seen on the server afterwards. If I login with a normal post outside and then try to request a page, it works fine. I also notice that chrome is sending along the following in the headers:
Cookie:_rexbro_session=g2wAAAABaAJkAAxjdXJyZW50X3VzZXJhAmo=--E0687A67DBE48DA40B6957CBCF6E83FB0E612660
This is not being sent via restangular requests.
I should also mention that when I login via restangular, the server is responding with the following header:
set-cookie:_rexbro_session=g2wAAAACaAJkAAxjdXJyZW50X3VzZXJhAmgCZAAEdXNlcmgIZAASRWxpeGlyLlVzZXIuRW50aXR5ZAALRWxpeGlyLlVzZXJhAm0AAAASYXZvaWRpYW1AZ21haWwuY29tbQAAAA1KYXlzb24gQmFpbGV5bQAAADwkMmEkMTAkNHNsQVFFRGRDcXd1R3JNNVYwOXBTLkx3MHpVeElNLy5tbVM2eTVmc3BFa3NUbHhuTUtiMzJoB2QAFEVsaXhpci5FY3RvLkRhdGVUaW1lYgAAB91hBGEcYRFhD2EUaAdkABRFbGl4aXIuRWN0by5EYXRlVGltZWIAAAfdYQVhA2EVYR5hFmo=--D3F8D9A8355421B8571DB691ED5C082AD183B034; path=/; HttpOnly
but I don't see anything being done with it.
Thanks in advance.
EDIT: I should have stated that my server storing the session, the api server, is separate from the server serving the frontend.
I think your are looking for this:
RestangularProvider.setDefaultHttpFields({
withCredentials: true
});
add this lines to app.config

Is there a way to avoid Preflighting with $http?

I'm using nginx on the remote server, and with no support for the OPTIONS method I've been terribly stuck. Both the server and angular refuse to talk to each other.
I just want to make a simple $http.post() request. Is there a way to configure the service to ONLY send the POST request, and not do any preflighting with OPTIONS?
This is not something AngularJS does, but something your browser does according to the Cross-Origin Resource Sharing standard. See also this answer on a related issue.
However, if you make it so that the AngularJS application is served from the same domain as your resource (different subdomains will affect cross-origin), then the browser will not send the OPTIONS request as the resource is no longer from a cross-origin server.
Example:
www.example.com requests resource on api.example.com will trigger OPTIONS request
www.example.com requests resource from www.example.com/api will not trigger OPTIONS request
If CORS is Unavoidable
You could change the header of the request to text/plain and then parse your response manually acording to answers in this link below
How to skip the OPTIONS preflight request in AngularJS

Setting cookie from WebApi via angularjs

I'm making a call to the WebApi service, which sets the cookie in the response object.
The call is made from angularjs via $resource
So this is the server code:
CookieHeaderValue cookie = new CookieHeaderValue("Token", "blah") { HttpOnly = true, Expires = DateTime.Now.AddYears(10), Path="/" };
response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
This works, I can see the Set-Cookie header in a response, however the cookie is not being set.
A friend of mine had to set xhrFields' withCredentials to true when he was using jQuery, so I wonder if there's something that needs to be configured in angular as well ?
There could be a number of things going on.
First, since you are on separate domains, you may need to implement CORs (cross origin resource sharing), but it seems that the request is being made successfully. I'm not sure why that works, I would think that browsers would prevent it. In any case here's a jsfiddle that illustrates using CORs with angularjs to make both $http & $resource requests. The trick seems to be to configure the $http service:
$http.defaults.useXDomain = true;
Another thought is that cookies from one domain, can't be accessed by another domain. Here is another question on cookies with angularjs, but the request and server seem to be on the same domain. Here is a discussion on cookie domains, and how they are applied.
If it's possible I would try to get the cookie request/response working on the same domain, and then move the client to another domain.

Resources