在前后端分离的开发模式中,React前端项目通常运行在本地3000端口,而Spring Security保护的后端服务可能运行在8080端口,两者源不同就会触发浏览器的CORS跨域限制,尤其是在调用登录接口时,很容易出现请求被拦截的情况。

跨域问题的产生原因
浏览器的同源策略要求协议、域名、端口完全一致才允许请求交互,不满足这个条件就会触发CORS校验。Spring Security默认会开启CSRF防护,同时没有配置跨域规则时,会直接拦截跨域的登录请求,返回403或者CORS相关的错误提示。
常见的报错信息会包含Access-Control-Allow-Origin相关的提示,说明后端没有允许前端所在的源发起请求。
React前端侧配置
React项目可以通过配置代理的方式规避开发环境的跨域问题,不需要修改后端代码就能临时解决本地调试的跨域限制。
方案一:修改package.json配置代理
在React项目的package.json中添加代理配置,将所有请求转发到后端服务地址:
// package.json 中添加以下配置
{
"name": "react-login-demo",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8080", // 后端Spring服务地址
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}方案二:使用http-proxy-middleware配置自定义代理
如果需要对代理规则做更细致的控制,可以安装http-proxy-middleware插件:
// 安装插件
// npm install http-proxy-middleware --save-dev
// 在src目录下创建setupProxy.js文件
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api', // 匹配以/api开头的请求
createProxyMiddleware({
target: 'http://localhost:8080', // 后端服务地址
changeOrigin: true, // 修改请求头中的origin为目标地址
pathRewrite: {
'^/api': '' // 去掉请求路径中的/api前缀
}
})
);
};Spring Security后端侧配置
后端配置是彻底解决跨域问题的核心,需要同时配置CORS规则和Spring Security的权限放行规则,确保登录接口可以被跨域访问。
配置CORS全局规则
创建一个CORS配置类,定义允许的源、请求方法和请求头:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 允许的前端源,生产环境替换为实际前端域名,多个用逗号分隔
config.addAllowedOrigin("http://localhost:3000");
// 允许所有请求方法
config.addAllowedMethod("*");
// 允许所有请求头
config.addAllowedHeader("*");
// 允许携带凭证(如Cookie)
config.setAllowCredentials(true);
// 对所有接口生效
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}Spring Security中放行登录接口并整合CORS
需要在Spring Security的配置中关闭CSRF防护(登录接口通常使用无状态鉴权时可以关闭),同时整合CORS配置,确保跨域请求不会被安全规则拦截:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.web.cors.CorsUtils;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 关闭CSRF防护,登录接口不需要CSRF校验
.csrf().disable()
// 整合CORS配置,使用上面定义的CORS规则
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话
.and()
.authorizeRequests()
// 放行登录接口,允许跨域访问
.antMatchers("/login").permitAll()
// 处理跨域预检请求,预检请求也需要放行
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
// 其他请求需要认证
.anyRequest().authenticated()
.and()
.formLogin() // 配置表单登录,也可以替换为JSON登录
.loginProcessingUrl("/login") // 登录接口地址
.permitAll();
}
}登录接口跨域注意事项
如果登录接口使用JSON格式传递参数,需要确保后端支持JSON格式的登录请求,同时前端的请求头要设置正确:
// React前端登录请求示例
const handleLogin = async (username, password) => {
try {
const response = await fetch('/api/login', { // 使用代理后不需要写完整后端地址
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
});
const data = await response.json();
console.log('登录结果:', data);
} catch (error) {
console.error('登录请求失败:', error);
}
};后端如果需要支持JSON格式的登录参数,还需要自定义登录过滤器,解析请求体中的JSON数据,避免默认的表单登录过滤器无法读取参数导致登录失败。
常见问题排查
- 检查前端发起请求的地址是否正确,代理配置是否生效
- 检查后端CORS配置的允许源是否包含前端项目的实际访问地址
- 检查Spring Security是否放行了登录接口和预检请求
- 如果携带Cookie,确认CORS配置中
setAllowCredentials设置为true,且允许源不能设置为*
注意:生产环境不要将CORS允许源设置为*,也不要随意关闭必要的Spring Security防护规则,需要根据实际业务场景调整配置,保障接口安全。
通过以上前后端的配置配合,就可以彻底解决React前端对接Spring Security登录时的CORS跨域问题,保障登录功能正常运行。
ReactSpring_SecurityCORS跨域登录接口修改时间:2026-05-30 23:42:48