4 votes

React App + Spring Boot - Le jeton d'authentification JWT à l'intérieur d'un cookie n'est pas défini dans Chrome

J'essaie de configurer Spring Boot pour qu'il mette en place un cookie contenant un jeton d'authentification JWT à la suite d'une demande de connexion depuis mon application react, et que le navigateur mette automatiquement en place ce cookie pour toutes les demandes, comme spécifié par le chemin du cookie. Le comportement est correct dans l'environnement de mon ami - même code, navigateur Chrome, machine différente. J'ai essayé d'effacer node_modules, mvn clean install, j'ai aussi essayé différents navigateurs Chrome et FireFox, sans succès.

Voici tout le code pertinent (faites-moi savoir si j'ai oublié quelque chose d'important)

  • React s'exécute sur localhost:3000
  • Spring Boot fonctionne sur localhost:8080
  • Il y a un proxy dans le package.json

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

Pour tester le flux d'authentification, nous émettons une demande de connexion à partir du formulaire de connexion (react), la demande est correctement mandatée vers le port 8080 et la réponse du serveur renvoie le jeton JWT dans le cadre d'un cookie d'authentification. Le cookie est spécifié dans l'élément /api chemin. Demande de réseau comme le montre le Chrome ci-dessous :

enter image description here

Immédiatement après la connexion, l'application react émet une deuxième requête HTTP vers le back-end, mais un point d'arrêt sur le serveur montre qu'aucun cookie n'est transmis par le navigateur dans le cadre de cette requête. La requête est adressée à http://localhost:3000/api/user .

Dans la partie frontale, nous utilisons fetch pour faire cette demande et cela ressemble à ceci :

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

Pour plus de clarté, voici comment nous renvoyons le cookie original du serveur, après une connexion réussie :

@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");
        }
    }

Y a-t-il quelque chose qui cloche dans notre approche ? Qu'est-ce qui pourrait empêcher mon navigateur de transmettre le cookie d'authentification ?

2voto

Anton Belev Points 1239

C'est embarrassant...

Le problème était cette ligne

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

!environment.acceptsProfiles(Profiles.of("dev")) a été évaluée à true et le cookie n'était transmis que si la connexion était sécurisée, ce qui n'était pas le cas puisqu'il s'agissait de localhost. Mystère résolu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X