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

如何在Ruby on Rails应用层面实现全路由加密

Rails应用全局路由加密实现方案

实现核心是在不修改原有业务代码的前提下,新增两层统一逻辑:加密路由生成逻辑、加密路由解析转发逻辑,全程兼容原有link_to、redirect_to、路由辅助方法的调用习惯。


步骤1:初始化路由加密工具

使用Rails内置的加密模块实现,无需额外引入第三方gem,在config/initializers目录下新建route_encryptor.rb:

# config/initializers/route_encryptor.rb
# 基于Rails自带密钥生成加密器,加密强度满足业务需求
ROUTE_ENCRYPTOR = ActiveSupport::MessageEncryptor.new(
  Rails.application.secret_key_base.byteslice(0..31),
  cipher: 'aes-256-gcm'
)

# 路径加密方法:原始路径段转URL安全的加密串
def encrypt_route_segments(segments)
  raw_encrypted = ROUTE_ENCRYPTOR.encrypt_and_sign(segments.join('/'))
  raw_encrypted.gsub('+', '-').gsub('/', '_').gsub('=', '')
end

# 路径解密方法:加密串还原为原始路径段,解密失败返回nil
def decrypt_route_segments(encrypted_str)
  normalized_str = encrypted_str.gsub('-', '+').gsub('_', '/')
  normalized_str += '=' * ((4 - normalized_str.length % 4) % 4)
  ROUTE_ENCRYPTOR.decrypt_and_verify(normalized_str).split('/')
rescue ActiveSupport::MessageEncryptor::InvalidMessage
  nil
end

步骤2:配置全局路由解析规则

修改config/routes.rb,新增加密路由的全局匹配转发逻辑,原有业务路由无需任何修改:

# config/routes.rb
Rails.application.routes.draw do
  # 加密路由匹配约束
  class EncryptedRouteConstraint
    def matches?(request)
      @decrypted_segments = decrypt_route_segments(request.path_info.delete_prefix('/'))
      @decrypted_segments.present?
    end

    def decrypted_segments
      @decrypted_segments
    end
  end

  # 加密路由优先级最高,捕获所有加密路径后转发到对应原始路由
  match '*encrypted_path', to: -> (env) {
    request = ActionDispatch::Request.new(env)
    constraint = EncryptedRouteConstraint.new
    if constraint.matches?(request)
      env['PATH_INFO'] = '/' + constraint.decrypted_segments.join('/')
      Rails.application.routes.router.serve(env)
    else
      [404, { 'Content-Type' => 'text/plain' }, ['Not Found']]
    end
  }, via: :all

  # ------------------- 以下是原有业务路由,无需修改 -------------------
  resources :users
  # 其他原有路由...
end

步骤3:覆写路由生成逻辑,自动加密输出URL

在config/initializers目录下新建route_url_override.rb,保证所有路由辅助方法自动输出加密后的路径:

# config/initializers/route_url_override.rb
module EncryptedRouteHelper
  def url_for(options = nil)
    original_url = super(options)
    # 跳过非本应用域名URL、静态资源路径、系统内置路径
    return original_url if original_url.start_with?('http') && !original_url.start_with?(root_url)
    return original_url if original_url.start_with?('/assets/', '/rails/active_storage/', '/rails/info/')

    uri = URI.parse(original_url)
    return original_url if uri.path == '/' || uri.path.blank?

    # 加密路径段,保留原有query参数和锚点
    encrypted_path = encrypt_route_segments(uri.path.delete_prefix('/').split('/'))
    new_path = "/#{encrypted_path}"
    new_path += "?#{uri.query}" if uri.query.present?
    new_path += "##{uri.fragment}" if uri.fragment.present?

    original_url.start_with?('http') ? URI.join(root_url, new_path).to_s : new_path
  rescue URI::InvalidURIError
    original_url
  end
end

# 把加密逻辑混入所有需要生成URL的场景
ActionView::Base.include EncryptedRouteHelper
ActionController::Base.include EncryptedRouteHelper
ActiveJob::Base.include EncryptedRouteHelper if defined?(ActiveJob)

注意事项

  • 可根据业务需求调整跳过加密的路径规则,比如后台管理路径、开放API路径可单独配置不加密
  • 更换加密密钥前需要做好旧密钥兼容逻辑,避免存量URL直接失效
  • 加密后的字符串默认是URL安全格式,不会出现特殊字符导致路由匹配失败的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:27:01