You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+AngularJS表单提交POST请求无法传递CSRF令牌问题求助

解决表单提交POST请求时CSRF令牌无效的问题

你的核心问题很明确:模板里的Spring EL表达式 ${_csrf.parameterName} 和 ${_csrf.token} 没有被正确解析,导致表单提交时传递的是字符串字面量而非实际的CSRF参数名和令牌值,所以Spring Security的CsrfFilter判定令牌无效,返回403 Forbidden。

下面是针对性的解决思路:

1. 适配模板引擎的语法规则

你当前的表单是纯HTML写法,但Spring EL表达式 ${} 需要对应的模板引擎来解析,不同引擎的语法要求不一样:

  • 如果用Thymeleaf(Spring Boot默认推荐):需要把隐藏域改成Thymeleaf的属性绑定方式,让引擎自动渲染出正确的参数名和令牌:

    <form id="w0" class="js_form_output" action="/output" method="post">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
        <button type="submit" class="button button_request">Apply now</button>
    </form>
    

    同时确保页面文件后缀是 .html,且项目已引入Thymeleaf依赖(Spring Boot默认已包含)。

  • 如果用JSP:需要将页面后缀改为 .jsp,并且在页面顶部添加指令开启EL表达式支持:

    <%@ page isELIgnored="false" %>
    

    这样JSP容器才会解析 ${_csrf.parameterName} 和 ${_csrf.token} 为实际值。

2. 手动从Cookie中获取令牌(备选方案)

因为你配置了 CookieCsrfTokenRepository.withHttpOnlyFalse(),CSRF令牌会存在名为 XSRF-TOKEN 的Cookie中(默认名称),可以通过JavaScript读取Cookie并动态设置隐藏域的值:

// 工具函数:根据Cookie名获取对应值
function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}

// 页面加载时自动设置CSRF令牌
window.addEventListener('load', () => {
    const csrfToken = getCookie('XSRF-TOKEN');
    // Spring Security默认的CSRF参数名是_csrf
    const csrfParam = '_csrf'; 
    const csrfInput = document.querySelector('input[name="${_csrf.parameterName}"]');
    if (csrfInput) {
        csrfInput.name = csrfParam;
        csrfInput.value = csrfToken;
    }
});

这种方式不依赖模板引擎,但不如引擎解析的方式简洁可靠。

3. 验证Spring Security配置的正确性

再次确认你的安全配置确实启用了正确的CSRF令牌仓库:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
        // 其他安全配置...
    }
}

withHttpOnlyFalse() 是关键配置——它允许前端JavaScript访问存储CSRF令牌的Cookie,这也是AngularJS能正常发起请求的原因(AngularJS会自动读取该Cookie并在请求头中携带 X-XSRF-TOKEN)。


内容的提问来源于stack exchange,提问作者vipme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:19:32