Anton Belev
Anton Belev

Reputation: 13603

React App + Spring Boot - JWT auth token inside a cookie is not set in Chrome

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)

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?

Upvotes: 5

Views: 4177

Answers (1)

Anton Belev
Anton Belev

Reputation: 13603

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.

Upvotes: 3

Related Questions