Spring @RestController not setting cookies with re

2019-07-19 11:58发布

问题:

I have the following rest endpoint that I would like to send a cookie along with my ResponseEntity. However after succesfully sending the response, the cookie is nowhere to be found.

@RequestMapping(value = "myPath", method = RequestMethod.POST)
public ResponseEntity<?> createToken(HttpServletResponse response)
    final String token = "a1b2c3d4e";

    Cookie cookie = new Cookie("token", token);
    response.addCookie(cookie);
    // Return the token
    return ResponseEntity.ok(new MyCustomResponse(token));
}

MyCustomResponse

class MyCustomResponse {
    private final String token;
    public MyCustomResponse(String token) {
        this.token = token;
    }
}

I have also tried creating the ResponseEntity manually and setting the cookie in the headers with the "Set-Cookie" header but same thing, no cookie.

edit: I have confirmed that the Set-Cookie header is in fact present in the response, however it is not actually being stored in the browser. I am using a static web-app running in WebStorm to access my rest endpoint running on a different port. This web app is just using JQuery's $ajax method to call the REST endpoint, nothing fancy. When I run the web app in WebStorm I am able to see the cookie it creates in my browser, so that confirms my browser is allowing cookie storage.

回答1:

I figured it out. My web application I am using to access my rest api is running on a different local port than my rest api. This causes the AJAX request to fail CORS requirements, thus the cookie doesnt actually get set.

I found the solution here What can cause a cookie not to be set on the client?

edit: I should add that it was adding the xhrFields snippet to JQuery's $ajax method that fixed it for me, the other parts weren't necessary.

(posting the answer below in case it gets deleted)

I think I found the solution. Since during development, my server is at "localhost:30002" and my web app at "localhost:8003", they are considered different hosts regarding CORS. Therefore, all my requests to the server are covered by CORS security rules, especially Requests with credentials. "Credentials" include cookies as noted on that link, so the returned cookie was not accepted because I did not pass

xhrFields: {
  withCredentials: true
}

to jQuery's $.ajax function. I also have to pass that option to subsequent CORS requests in order to send the cookie.

I added the header Access-Control-Allow-Credentials: true on the server side and changed the Access-Control-Allow-Origin header from wildcard to http://localhost:8003 (port number is significant!). That solution now works for me and the cookie gets stored.