React App + Spring Boot - cookie 中的 JWT 身份验证令牌未在 Chrome 中设置

Ant*_*lev 5 cookies google-chrome setcookie reactjs spring-boot

我正在尝试将 Spring Boot 配置为在来自我的 React 应用程序的登录请求之后设置包含 JWT 身份验证令牌的 cookie,然后期望浏览器会自动将此 cookie 设置为 cookie 路径指定的所有请求。行为在我朋友的环境中没问题 - 相同的代码,Chrome 浏览器,不同的机器。我尝试清除 node_modules,mvn clean install,还尝试了不同的浏览器 Chrome 和 FireFox,但没有成功。

这是所有相关的代码(如果我遗漏了其他重要的东西,请告诉我)

  • React 在 localhost:3000 上运行
  • Spring Boot 在 localhost:8080 上运行
  • package.json 中有一个代理

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

为了测试身份验证流程,我们从登录表单 (react) 发出登录请求,该请求成功代理到端口 8080,并且来自服务器的响应成功返回 JWT 令牌作为身份验证 cookie 的一部分。cookie 被指定为/api路径。如下 Chrome 中所示的网络请求:

在此处输入图片说明

登录后,react 应用程序立即向后端发出第二个 HTTP 请求,但服务器上的断点显示没有 cookie 作为此请求的一部分从浏览器传递。请求是http://localhost:3000/api/user

在前端,我们fetch用来发出该请求,它看起来像这样:

fetch("/api/user, {
    credentials: "same-origin"
  })
Run Code Online (Sandbox Code Playgroud)

仅作为附加上下文,这是我们在成功登录后从服务器返回原始 cookie 的方式:

@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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我们的方法有什么问题吗?什么可能阻止我的浏览器传递 auth cookie?

Ant*_*lev 2

哦,这太尴尬了……

问题是这一行

cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
Run Code Online (Sandbox Code Playgroud)

!environment.acceptsProfiles(Profiles.of("dev"))正在评估true,它导致只有在连接安全的情况下才会传递 cookie,但事实并非如此,因为它是本地主机。谜团已揭开。