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

如何在不丢失会话与ActionText附件的情况下轮换secret_key_base

Rails 6.1.7 轮换 secret_key_base 实操方案(不丢会话+保住ActionText附件)

一、核心目标

轮换应用的secret_key_base,同时做到:

  • 现有用户会话不失效
  • ActionText关联的附件链接能正常访问

二、会话与Cookie的无缝轮换配置

Rails的secret_key_base会派生出签名Cookie和加密Cookie的密钥,要实现无缝切换,需要让应用同时支持新旧密钥验证。直接在config/application.rb(或生产环境配置文件)中添加以下代码:

Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
  # 替换成你的旧secret_key_base
  old_secret_key_base = "xxxxxxxxxxxxxxxxx"

  # 配置签名Cookie的旧密钥支持
  old_signed_secret = Rails.application.message_verifier(:signed_cookie).send(:secret, old_secret_key_base)
  cookies.rotate :signed, old_signed_secret

  # 配置加密Cookie的旧密钥支持
  old_encryptor = ActiveSupport::MessageEncryptor.new(old_secret_key_base, cipher: "aes-256-gcm")
  cookies.rotate :encrypted, old_encryptor.secret
end

这段代码的作用是:应用会先用新的secret_key_base生成新会话,同时保留旧密钥验证现有会话。等所有活跃用户都生成新会话后(通常1-2周),再删掉这段代码即可。

三、ActionText/ActiveStorage附件保护

ActionText的附件依赖ActiveStorage的签名URL,这些URL是用secret_key_base签名的。要让旧的附件链接依然有效,在config/initializers/secret_rotation.rb里添加以下初始化代码:

Rails.application.config.after_initialize do
  old_secret_key_base = "xxxxxxxxxxxxxxxxx" # 同样替换成旧密钥

  verifier_class = if ActiveStorage::Blob.service_urls_expire_in.present?
    ActiveStorage::VerifiedKeyWithExpiration
  else
    ActiveStorage::VerifiedKey
  end

  # 重写验证逻辑,先试新密钥,失败再用旧密钥
  original_verify = verifier_class.method(:verify)
  verifier_class.define_singleton_method(:verify) do |message, **options|
    begin
      original_verify.call(message, **options)
    rescue ActiveSupport::MessageVerifier::InvalidSignature
      old_verifier = ActiveSupport::MessageVerifier.new(old_secret_key_base, digest: "SHA256", serializer: JSON)
      old_verifier.verify(message, **options)
    end
  end
end

这样用户访问旧的附件链接时,应用会自动用旧密钥验证,不会出现失效的情况。

四、开发环境测试踩坑指南

开发环境中Rails默认会从应用名派生secret_key_base,但手动设置后会覆盖这个逻辑。如果修改密钥后ActionText附件失效,改回也无法恢复,试试这几步:

  • 执行rails tmp:clear清除临时缓存文件
  • 清空浏览器缓存,或用隐私窗口重新测试
  • 确认旧密钥的拼写完全正确,没有多余空格或字符

五、完整轮换流程

  1. 把上述两段配置代码添加到应用中,部署到生产环境
  2. 等待1-2周,确保所有活跃用户都生成了新会话,旧的附件链接也都被访问过
  3. 移除配置中的轮换代码,只保留新的secret_key_base
  4. 再次部署应用,完成密钥轮换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:45:24