从AJAX请求返回CSRF令牌的Symfony表单无效

从AJAX请求返回CSRF令牌的Symfony表单无效,ajax,session,redis,csrf,symfony4,Ajax,Session,Redis,Csrf,Symfony4,我们有一个Symfony 4.3应用程序,它有一个可以发出多个AJAX请求的页面。每个AJAX响应都包含几个表单,每个表单都有自己的CSRF令牌。但是,只有一个AJAX调用能够将其令牌存储在会话中。因此,AJAX请求中的所有表单都将失败,并显示消息 CSRF令牌无效。请尝试重新提交表单。 除了一个表单,该表单设法在会话中正确保存其令牌 会话存储在redis中 在进行多个AJAX调用时,如何确保所有CSRF令牌都存储在会话中?CSRF令牌部分使用cookies。当您在一个页面上生成两个CSRFs并

我们有一个Symfony 4.3应用程序,它有一个可以发出多个AJAX请求的页面。每个AJAX响应都包含几个表单,每个表单都有自己的CSRF令牌。但是,只有一个AJAX调用能够将其令牌存储在会话中。因此,AJAX请求中的所有表单都将失败,并显示消息

CSRF令牌无效。请尝试重新提交表单。

除了一个表单,该表单设法在会话中正确保存其令牌

会话存储在redis中


在进行多个AJAX调用时,如何确保所有CSRF令牌都存储在会话中?

CSRF令牌部分使用cookies。当您在一个页面上生成两个CSRFs并提交其中一个表单时,您将使cookie无效

如果没有对框架本身进行一些扩展,我只能看到解决这个问题的一种方法——这是相当迂回的:

你可以做的是设置一个控制器来生成你的应用程序表单

      $.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
});
在初始页面加载时,控制器将加载登录表单和应用表单。在通过AJAX提交登录表单时,您还将只请求应用表单的控制器(这也将给用户一个新的cookie)。使用javascript,您可以从新表单中提取新的csrf令牌,并将其注入原始应用表单。然后,当您提交应用程序表单时,它应该有一个新的、有效的csrf令牌

举例说明:

获取应用程序表单和登录表单->通过AJAX提交登录->在后台通过AJAX获取应用程序表单->窃取新应用程序表单的csrf令牌并将其注入第一个应用程序表单->提交应用程序表单

      $.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
});
将此添加到标题->>

<meta name="csrf-token" content="{{ csrf_token() }}">

我认为cookie只是存储了PHPSESSID。然后,服务器使用PHPSESSID检索存储在服务器上的实际会话。在我的例子中,会话存储在REDIS实例中。所以我不确定我是否理解你的解决方案。另外,需要明确的是,所有表单都有一个CSRF令牌。问题是服务器没有将其存储在用户会话中。