React App + Spring 引导 - Chrome 中未设置 cookie 中的 JWT 身份验证令牌
React App + Spring Boot - JWT auth token inside a cookie is not set in Chrome
我正在尝试配置 Spring 引导到包含 JWT 身份验证令牌的 set-cookie 遵循来自我的 React 应用程序的登录请求,然后期望浏览器会自动将此 cookie 设置为cookie 路径指定的所有请求。在我朋友的环境中行为正常 - 相同的代码,Chrome 浏览器,不同的机器。我试过清除 node_modules、mvn clean install,也试过不同的浏览器 Chrome 和 FireFox,都没有成功。
这是所有相关代码(如果我遗漏了其他重要内容,请告诉我)
- React 在 localhost:3000
上 运行
- Spring 在 localhost:8080
上 运行 启动
package.json
中有代理
"proxy": "http://localhost:8080",
为了测试身份验证流程,我们从登录表单(反应)发出登录请求,该请求已成功代理到端口 8080,并且服务器的响应已成功 returning JWT 令牌作为身份验证 cookie 的一部分。 cookie 指定到 /api
路径。如下 Chrome 所示的网络请求:
登录后,React 应用程序立即向后端发出第二个 HTTP 请求,但服务器上的断点显示没有从浏览器传递任何 cookie 作为此请求的一部分。请求是 http://localhost:3000/api/user
.
在前端,我们使用 fetch
发出该请求,它看起来像这样:
fetch("/api/user, {
credentials: "same-origin"
})
仅供参考,这就是我们在成功登录后 return 来自服务器的原始 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");
}
}
我们的做法有什么问题吗?是什么阻止了我的浏览器传递身份验证 cookie?
哦,这很尴尬...
问题出在这一行
cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
!environment.acceptsProfiles(Profiles.of("dev"))
评估为 true
并且它导致仅在连接安全时才传递 cookie,这不是因为它是本地主机。谜底揭晓。
我正在尝试配置 Spring 引导到包含 JWT 身份验证令牌的 set-cookie 遵循来自我的 React 应用程序的登录请求,然后期望浏览器会自动将此 cookie 设置为cookie 路径指定的所有请求。在我朋友的环境中行为正常 - 相同的代码,Chrome 浏览器,不同的机器。我试过清除 node_modules、mvn clean install,也试过不同的浏览器 Chrome 和 FireFox,都没有成功。
这是所有相关代码(如果我遗漏了其他重要内容,请告诉我)
- React 在 localhost:3000 上 运行
- Spring 在 localhost:8080 上 运行 启动
package.json
中有代理"proxy": "http://localhost:8080",
为了测试身份验证流程,我们从登录表单(反应)发出登录请求,该请求已成功代理到端口 8080,并且服务器的响应已成功 returning JWT 令牌作为身份验证 cookie 的一部分。 cookie 指定到 /api
路径。如下 Chrome 所示的网络请求:
登录后,React 应用程序立即向后端发出第二个 HTTP 请求,但服务器上的断点显示没有从浏览器传递任何 cookie 作为此请求的一部分。请求是 http://localhost:3000/api/user
.
在前端,我们使用 fetch
发出该请求,它看起来像这样:
fetch("/api/user, {
credentials: "same-origin"
})
仅供参考,这就是我们在成功登录后 return 来自服务器的原始 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");
}
}
我们的做法有什么问题吗?是什么阻止了我的浏览器传递身份验证 cookie?
哦,这很尴尬...
问题出在这一行
cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
!environment.acceptsProfiles(Profiles.of("dev"))
评估为 true
并且它导致仅在连接安全时才传递 cookie,这不是因为它是本地主机。谜底揭晓。