Potatosaurus
Potatosaurus

Reputation: 475

Unable to access a response cookie in Angular.js

I am attempting to extract the cookies from a response to a $http request.
The request comes back just fine, along with the cookie, however I am unable to get the cookie so I can store it.
A picture of the response suggests that everything is normal.

enter image description here

However if I try to extract the value of the Set-Cookie header through a method such as

.then(function(response) {
     //First function handles success
     log(response.data);
     registrationOutcomeText = response.data;
     log(response.headers('Set-Cookie'));
}

I am unable to do so as I receive a null result.

By examining my cookies, I know that it's not getting saved, so something such as

$cookies.get("AuthToken")

will not work.

Upvotes: 1

Views: 1899

Answers (2)

Potatosaurus
Potatosaurus

Reputation: 475

Right, so this solution is potentially horrible, but I feel it is necessary. The reasons being that:

  1. Trying to access the cookie through headers.('set-cookie') does not work, and returns null. I've attempted to rectify this through setting the expose headers option in my CORS filter on the server, however this still did not work.
  2. I need to be able to access the cookie value so I can save it to my domain's cookies, since this is a key step in specifying how long to retain the cookie for. Else, it expires at the end of the browsing session which is no good.
  3. Simply using with-credentials: true is not sufficient, as the cookie is then stored under the domain of my server, not the front end site. As such due to XSS protections, the cookie cannot be accessed by my site. I needed to be able to save the cookie to the site's storage, primarily due to what was outlined in reason two.

As such, here is what I did to resolve these issues.

On my server, I added a new custom header, "Authentication", to the response. This can be done by adding the following to a response:

    .header("Authentication", authToken)

(For example)

return Response.status(200).entity(message).header("Authentication", authToken).build();

Next, I needed to expose this custom header in my CORS filter.
Since I have a Java server, this is how my CORS filter looks:

@Provider
public class NewCrossOriginResourceSharingFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext response) {
        response.getHeaders().putSingle("Access-Control-Allow-Origin", [My site]);
        response.getHeaders().putSingle("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE");
        response.getHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type");
        response.getHeaders().putSingle("Access-Control-Expose-Headers", "Authentication");
        response.getHeaders().putSingle("Access-Control-Allow-Credentials", true);
    }

}

Note that this won't work if directly copied and pasted, as you need to replace the [My site] value with your own domain, else your requests won't satisfy the CORS filter.

Finally, this now means that on the client side I can access the header "Authentication" easily as seen below.

.then(function(response) {
        $scope.registrationOutcomeText = response.data;
        console.log(response.headers("Authentication"));
    }

Response.

From there I am able to access, store and retrieve the cookie in a manner that resolves all three of the issues initially identified at the start of the answer.

Upvotes: 1

Redd Sanso
Redd Sanso

Reputation: 51

I think your solution could be intercept responses as in the "Transforming requests and responses" section in the docs: https://docs.angularjs.org/api/ng/service/$http

Upvotes: 0

Related Questions