首页 > 解决方案 > 有时无法在常规 Web 应用程序中验证 CSRF 令牌的真实性

问题描述

我有一个使用表单的简单 Rails 6 应用程序

<%= bootstrap_form_with(model: event, local: true, html: { multipart: true }) do |form| %>

在生成的 HTML 中,我有这是标题

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="SOME TOKEN" />

并以形式

<input type="hidden" name="authenticity_token" value="SOME OTHER TOKEN" />

通常一切正常,但有时我会收到错误

Can't verify CSRF token authenticity.

日志显示令牌已在参数中传递,我无法找出验证失败的原因。我确信没有恶意使用或类似的东西。

CSRF 令牌失去其有效性有什么原因吗?也许它只在一定时间内有效?

标签: ruby-on-railscsrfruby-on-rails-6

解决方案


Rails 中的 CSRF 保护通过在提交的表单以及用户会话中存储一个随机值作为字段来工作。如果提交表单时值不匹配,Rails 将拒绝表单提交请求。

如果您在 Rails 中使用默认的 cookie 会话存储,那么会话将不会过期(直到 cookie 过期)。如果您正在使用其他东西(文件或数据库支持的会话),那么是的,如果这些会话过期,表单提交将失败并出现 CSRF 错误。

因此,如果您使用基于 cookie 的会话(默认),请检查 cookie 到期时间。如果看起来没问题,那可能是其他问题。


推荐阅读