Spring Security POST请求403问题:无需禁用CSRF的方案咨询(Spring Boot3.1.2)
无需禁用CSRF让POST请求正常工作的方法
你的问题根源是Spring Security默认启用了CSRF防护,POST、PUT、DELETE这类"非安全"HTTP方法必须携带有效的CSRF令牌,否则会被拦截返回403。以下是几种无需禁用CSRF的解决方案:
1. 前端请求携带CSRF令牌
Spring Security默认会将CSRF令牌存储在名为XSRF-TOKEN的Cookie中(默认HttpOnly属性为true,前端JS无法直接读取),你可以先修改后端配置让Cookie允许前端读取,再在请求头中携带令牌:
后端配置(允许前端读取CSRF Cookie)
在Spring Security配置类中,调整CSRF令牌的存储方式:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .formLogin(form -> form.permitAll()) .csrf(csrf -> csrf // 设置Cookie允许前端JS读取,同时指定Cookie和请求头名称 .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) ); return http.build(); } }
前端携带令牌示例
- 用Axios发送请求时,可全局配置自动携带令牌:
axios.defaults.xsrfCookieName = 'XSRF-TOKEN'; axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';
- 原生JS请求:
function getCookie(name) { let value = "; " + document.cookie; let parts = value.split("; " + name + "="); if (parts.length === 2) return parts.pop().split(";").shift(); } fetch('/DbUserHandling/createNewUser', { method: 'POST', headers: { 'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'), 'Content-Type': 'application/json' }, body: JSON.stringify(/* 请求体数据 */) });
2. 表单提交场景(传统后端渲染页面)
如果是通过HTML表单提交POST请求,只需在表单中添加一个隐藏的CSRF令牌字段,Spring Security会自动识别并验证:
<form action="/DbUserHandling/createNewUser" method="post"> <!-- 其他表单字段 --> <input type="hidden" name="_csrf" th:value="${_csrf.token}"> <button type="submit">提交</button> </form>
(注:上面用了Thymeleaf的表达式,如果你用其他模板引擎,替换成对应获取CSRF令牌的方式即可)
3. 针对非浏览器客户端(如接口测试工具、后端服务调用)
如果是Postman、curl这类非浏览器工具调用接口,你可以先通过登录接口获取CSRF令牌,再在请求中携带:
- 先发送GET请求到登录页面或专门的令牌端点,从响应Cookie中提取
XSRF-TOKEN - 在POST请求的头中添加
X-XSRF-TOKEN字段,值为提取到的令牌
注意:除非你的应用是纯后端服务(仅被其他后端服务调用,无浏览器访问),否则不建议禁用CSRF防护,它能有效防止跨站请求伪造攻击,保护用户数据安全。
内容的提问来源于stack exchange,提问作者Ayush Gupta
相关产品推荐
相关产品推荐

