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

Rails 7中Invisible Captcha时间戳阈值与Devise confirmable不触发问题

问题:Rails 7 + Devise 环境下Invisible Captcha时间戳验证未生效

部署在fly.io上的Rails 7应用新增了约10个机器人账号,已安装配置Invisible Captcha gem,设置400秒时间戳阈值后验证未触发。当前环境情况:

  • Devise启用confirmable选项,用户需点击确认链接才能访问站点
  • 使用TomSelect JS实现注册时角色选择
  • 注册表单能看到<%= invisible_captcha %>生成的隐藏字段,HTML结构如下:
<div class="akycjhmgilspxv_1669858439"><style media="screen">.akycjhmgilspxv_1669858439 {position:absolute!important;height:1px;width:1px;overflow:hidden;}</style><label for="akycjhmgilspxv">How often do you go out dancing?</label><input type="text" name="akycjhmgilspxv" id="akycjhmgilspxv" autocomplete="off" tabindex="-1"><input type="hidden" name="spinner" id="spinner" value="0427cfe9c26b1956983b7f12163dbb94" autocomplete="off"></div>

相关配置代码:

  1. routes.rb:
devise_for :users, :path => '', :path_names => { :sign_in => "login", :sign_out => "logout", :sign_up => "register" }, controllers: { registrations: 'users/registrations' }

devise_scope :user do
  match '/register.user', to: 'devise/registrations#create', via: :post
end
  1. config/initializers/invisible_captcha.rb:
InvisibleCaptcha.setup do |config|
  # config.honeypots           << ['more', 'fake', 'attribute', 'names']
  # config.visual_honeypots    = false
  config.timestamp_threshold = 400
  # config.timestamp_enabled   = true
  # config.injectable_styles   = false
  # config.spinner_enabled     = true

  # Leave these unset if you want to use I18n (see below)
  config.sentence_for_humans     = 'How often do you go out dancing?'
  config.timestamp_error_message = 'Something went wrong, please try again.'
end
  1. 注册控制器:
class Users::RegistrationsController < Devise::RegistrationsController
  # before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]
  invisible_captcha only: [:create]
end

已重启服务器,但400秒阈值仍未生效,疑惑是否只能依赖机器人填写隐藏字段来拦截。


排查与解决步骤

1. 启用时间戳验证核心开关

你的初始化配置里config.timestamp_enabled = true被注释掉了,这是时间戳验证生效的必要条件。取消注释该配置:

InvisibleCaptcha.setup do |config|
  # ...其他保留配置
  config.timestamp_threshold = 400
  config.timestamp_enabled   = true # 取消注释这行
  # ...其他保留配置
end

修改后重新部署应用,确保配置生效。

2. 修正路由指向自定义控制器

你额外添加的match '/register.user', to: 'devise/registrations#create', via: :post路由,指向了Devise默认的注册控制器,而非你添加了invisible_captcha回调的自定义控制器users/registrations。

要么删除这条冗余路由,要么修改为指向自定义控制器:

devise_scope :user do
  match '/register.user', to: 'users/registrations#create', via: :post
end

确保所有注册请求都经过带验证码验证的控制器动作。

3. 排除TomSelect的干扰

TomSelect本身不会影响验证码,但如果你的JS代码在表单提交前有修改字段、篡改提交时间的操作,可能导致时间戳验证失效。可以暂时禁用TomSelect测试注册流程,验证时间戳是否生效。

4. 检查请求参数完整性

查看机器人提交的请求日志,确认是否携带了spinner字段(时间戳参数)。如果机器人请求未携带该参数,时间戳验证应该触发拦截;若参数被篡改,也会触发验证失败。

5. 补充honeypot字段增强拦截

如果时间戳验证仍有遗漏,可以添加多个假字段(honeypot),增加机器人误填概率:

InvisibleCaptcha.setup do |config|
  config.honeypots << ['favorite_color', 'pet_name'] # 添加额外隐藏假字段
  # ...其他保留配置
end

这些字段对正常用户不可见,机器人若填写则会被直接拦截。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:30:50