更新
由于被推动实现调试日志,我现在可以看到问题是Spring报告了一个为notices控制器找到的无效CSRF令牌。到目前为止,我已经检查了postman生成的头文件,并将它们与通过获取请求生成的头文件进行了比较,未发现差异。生成的令牌已成功放入请求标头中。不幸的是,Spring日志中没有任何可辨别的内容,因此调试继续进行。
我正在学习Spring Security,目前正在将前端React部分连接到Spring后端。我遇到了麻烦,因为当向所需端点发出POST
请求时,它返回错误401。这让我很困惑,因为我相信我已经正确配置了CORS,并且还将端点标记为允许所有端点。
简而言之,该进程调用端点/token
以获取CSRF令牌,然后调用/notices
并将令牌作为头文件传入。如果使用Postman完成,该进程将按预期工作,因此我认为这是CORS问题,但是,我尝试在不同端口上运行前端,它被CORS阻止,因此我认为问题在其他地方。
一些附加信息:
/notices
和/token
都是POST
操作。- Spring后端和React前端都在同一台本地机器上运行。
- 收到错误代码401
前端JavaScript调用的代码为:
const debugNotices = () => {
let tokenData:any;
fetch('http://localhost:8080/token', {method:"POST"})
.then((response) => response.json())
.then((data) => tokenData = data).then((data:any) => fetch("http://localhost:8080/notices",
{
method:"POST",
headers: {
"X-XSRF-TOKEN": tokenData.token
}
}))
}
Spring安全配置:
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.cors()
.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
config.setAllowedMethods(Collections.singletonList(("*")));
config.setAllowCredentials(true);
config.setAllowedHeaders(Collections.singletonList("*"));
config.setMaxAge(3600L);
return config;
}
})
.and()
.csrf()
.ignoringRequestMatchers("/contact", "/register", "/token")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.securityContext()
.requireExplicitSave(false)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authorizeHttpRequests()
.requestMatchers("/myAccount", "/myBalance", "/myLoans", "/myCards", "/user").authenticated()
.requestMatchers("/notices", "/contact", "/register", "/test", "/token").permitAll()
.and()
.httpBasic()
.and()
.formLogin();
return http.build();
}
我试过在请求正文中包含credentials:'include'
,但是它会导致一个登录提示,我不相信这是我要找的方向。
我还尝试过手动插入CSRF令牌,而不是从服务器请求数据,但都失败了。
我还测试了CORS,就我所知,从localhost:3000
以外的任何地方访问端点都会被拒绝,并出现预期的CORS错误。
1条答案
按热度按时间4dbbbstv1#
此问题仅在从 localhost:portNumber 访问React前端时发生,我能够通过使用本地IP地址代替localhost来完全解决此问题。
我仍然不确定为什么在URL中使用localhost会有问题,如果你知道的话,我很想听听为什么会发生这种情况。