5

I'm trying to configure Spring Boot to set-cookie containing JWT auth token following a sign-in request from my react app, and then the expectation is that the browser will automatically set this cookie to all requests as specified by the cookie path. The behaviour is ok on my friend's environment - same code, Chrome browser, different machine. I tried clearing node_modules, mvn clean install, also tried different browsers Chrome and FireFox, no success.

Here is the all the relevant code (let me know if I'm missing something else important)

  • React is running on localhost:3000
  • Spring Boot is running on localhost:8080
  • There is a proxy in the package.json

    "proxy": "http://localhost:8080",

To test the auth flow we are issuing a sign-in request from the sign-in form (react), the request is successfully proxied to port 8080 and the response from the server is successfully returning the JWT token as part of an auth cookie. The cookie is specified to the /api path. Network request as seen in Chrome below:

enter image description here

Immediately after the login, the react app is issuing a second HTTP request to the back-end, but a break-point on the server shows no cookies are passed from the browser as part of this request. The request is to http://localhost:3000/api/user.

In the front-end we are using fetch to make that request and it looks like this:

fetch("/api/user, {
    credentials: "same-origin"
  })

Just for additional context this is how we return the original cookie from the server, upon a successful login:

@PostMapping("/signin")
    public ResponseEntity signin(@RequestBody AuthenticationRequest data, HttpServletResponse response) {
        try {
            String username = data.getUsername();
            Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, data.getPassword()));
            User user = (User) authentication.getPrincipal();
            String token = jwtTokenProvider.createToken(user);
            final Cookie cookie = new Cookie("auth", token);
            cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
            cookie.setHttpOnly(true);
            cookie.setMaxAge(Integer.MAX_VALUE);
            cookie.setPath("/api");
            response.addCookie(cookie);

            return ok(buildUserResponseObject(user));
        } catch (AuthenticationException e) {
            throw new BadCredentialsException("Invalid username/password supplied");
        }
    }

Is there anything wrong with our approach? What could be preventing my browser from passing on the auth cookie?

Anton Belev
  • 11,963
  • 22
  • 70
  • 111

1 Answers1

2

Oh this is embarrassing...

The issue was this line

cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));

!environment.acceptsProfiles(Profiles.of("dev")) was evaluating to true and it was causing the cookie to be only passed if the connection is secure, which it wasn't because it was localhost. Mystery solved.

Anton Belev
  • 11,963
  • 22
  • 70
  • 111
  • I faced with the same problem, I created a cookie the same as yours and it presents in headers set-cookie but not in application cookies. How can I solve that, what could be my problem ? I am using react axios. – ZootHii Nov 14 '21 at 13:28