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

如何重写Rails ActiveStorage的DirectUploadsController#create添加自定义请求头?

如何重写ActiveStorage::DirectUploadsController以添加自定义请求头?

问题描述

我想了解是否可以重写调用私有方法direct_upload_json的ActiveStorage::DirectUploadsController#create方法,原代码如下:

class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
  def create
    blob = ActiveStorage::Blob.create_before_direct_upload!(blob_args)
    render json: direct_upload_json(blob)
  end
  private
  ...
  def direct_upload_json(blob)
    blob.as_json(root: false, methods: :signed_id).merge(direct_upload: { url: blob.service_url_for_direct_upload, headers: blob.service_headers_for_direct_upload })
  end
end

我需要在请求头中设置Authorization Bearer <token>以及另一组键值对,请问有什么解决办法?谢谢。

解决方案

当然可以实现这个需求!最稳妥的方式是继承原控制器并重写关键方法,避免直接修改Rails源码带来的兼容性问题。以下是具体步骤:

1. 创建自定义DirectUploads控制器

在app/controllers目录下新建direct_uploads_controller.rb,继承自ActiveStorage的原控制器,然后重写私有方法direct_upload_json来注入自定义请求头:

class DirectUploadsController < ActiveStorage::DirectUploadsController
  private

  def direct_upload_json(blob)
    # 先获取存储服务默认生成的请求头
    default_headers = blob.service_headers_for_direct_upload

    # 合并自定义请求头:这里添加Authorization和你的自定义键值对
    custom_headers = default_headers.merge(
      "Authorization" => "Bearer #{get_auth_token}",
      "X-Your-Custom-Header" => "your-custom-value" # 替换为实际的键值对
    )

    # 按照原方法的结构构建响应JSON,替换headers部分
    blob.as_json(root: false, methods: :signed_id).merge(
      direct_upload: {
        url: blob.service_url_for_direct_upload,
        headers: custom_headers
      }
    )
  end

  # 自定义方法:根据你的业务逻辑获取认证token
  def get_auth_token
    # 示例:从当前登录用户获取token,或者从请求头中提取
    current_user&.auth_token || request.headers["X-Provided-Token"]
  end
end

2. 更新路由配置

修改config/routes.rb,把ActiveStorage的直接上传路由指向你的自定义控制器:

Rails.application.routes.draw do
  # 替换默认的direct_uploads路由
  direct_uploads route: "direct_uploads#create"

  # 其他路由配置...
end

备选方案:猴子补丁(不推荐)

如果你不想创建新控制器,也可以通过猴子补丁直接修改原控制器的方法,但这种方式在Rails版本升级时可能出现兼容性问题,仅在特殊场景下使用:

# 在config/initializers/active_storage_custom_headers.rb中添加
ActiveStorage::DirectUploadsController.class_eval do
  private

  def direct_upload_json(blob)
    default_headers = blob.service_headers_for_direct_upload
    custom_headers = default_headers.merge(
      "Authorization" => "Bearer #{get_auth_token}",
      "X-Your-Custom-Header" => "your-custom-value"
    )

    blob.as_json(root: false, methods: :signed_id).merge(
      direct_upload: {
        url: blob.service_url_for_direct_upload,
        headers: custom_headers
      }
    )
  end

  def get_auth_token
    # 你的token获取逻辑
    current_user&.auth_token
  end
end

关键说明

  • direct_upload_json方法负责生成前端上传文件所需的配置,包括上传URL和请求头。我们在这里添加的自定义头会被前端用于后续的文件上传请求,确保存储服务能验证身份或接收自定义信息。
  • 请根据你的实际业务场景调整get_auth_token方法,比如从当前用户会话、请求参数或自定义请求头中获取token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:22:47