通过自定义控制器操作将ActiveStorage文件发送给用户

尼尔

我知道ActiveStorageurl_for(user.avatar)方法。例:

<%= link_to "Download this file", url_for(@user.avatar) %>

很好,但是看起来好像没有授权建立。知道此链接的任何人都可以下载此文档。

过去,当我使用paperclip时,我有一个指向自定义控制器操作的链接。该自定义控制器操作完成了授权,如果一切正常,那么我曾经send_file将文件发送给用户。就像这样:

def deliver_the_file
  authorize :my_authorization
  send_file @user.avatar.path
end

如何使用active_storage执行此操作?我要做的就是url_for完全不授权用户实现。

我正在特别关注ActiveStorage上《 Rails指南》的“下载文件”部分。

相关示例代码:

# model 
class Book < ApplicationRecord
  has_one_attached :book_cover
end


class BooksController < ApplicationController
 ... 

  # custom action to authorize and then deliver the active_storage file
  def deliver_it
    # ... assume authorization already happened
    send_file rails_blob_path(@book.book_cover, disposition: "attachment")
  end
end

出现错误并说:

无法读取文件

我也尝试过这样:

def deliver_it
  # ... assume authorization already happened
  send_file @book.book_cover.download
end

这返回了错误:

字符串包含空字节

我也尝试过这样:

def deliver_it
  @book.book_cover.download
end

这返回了错误:

BooksController#deliver_it缺少此请求的模板

我也尝试过这个:

def deliver_it
  send_file @book.book_cover.blob
end

出现错误并说:

没有将ActiveStorage :: Blob隐式转换为String

乔治·克拉格霍恩

最好的选择是使用ActiveStorage::Blob#service_url重定向到Blob的签名的短期URL:

class Books::CoversController < ApplicationController
  before_action :set_active_storage_host, :set_book

  def show
    redirect_to @book.cover.service_url
  end

  private
    def set_active_storage_host
      ActiveStorage::Current.host = request.base_url
    end

    def set_book
      @book = Current.person.books.find(params[:book_id])
    end
end

或者,您自己提供文件。您可以ActionController::Live用来将文件流式传输到客户端,而不必一次将整个文件读入内存。

class Books::CoversController < ApplicationController
  include ActionController::Live

  before_action :set_book

  def show
    response.headers["Content-Type"] = @book.cover.content_type
    response.headers["Content-Disposition"] = "attachment; #{@book.cover.filename.parameters}"

    @book.cover.download do |chunk|
      response.stream.write(chunk)
    end
  ensure
    response.stream.close
  end

  # ...
end

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何通过ajax将图像数据作为参数发送给spring控制器

无法将视图数据下拉列表的选定值发送给我的控制器操作?

JSON数组以空发送给控制器

$ emit仅发送给直接父控制器

Axios在删除时将POSITION而不是ID发送给控制器

通过控制器的HTTPGET方法将动态变量传递给自定义操作过滤器

通过WMIC命令自动将文件发送给所有网络用户

将附件文件从CouchDB发送给用户?

通过OLAP连接将Excel文件发送给客户

Rails控制器-继承自定义操作

插件/自定义代码在插件更新可用时通过电子邮件发送给我

将“ Id”选中的复选框传递给模式引导程序并发送给控制器

使用自定义路由将aspnetcore路由到控制器操作

如何通过自定义控制器 drupal 8 将变量传递给主题模板

发送给用户后删除文件

将ActionCable发送给特定用户

将自定义表单值传递给自定义控制器操作

提交Ajax表单,但没有发送给控制器吗?

CakePHP下拉表单值未发送给控制器

在Thymeleaf中,如何获取HTML变量并将其发送给控制器?

设置发送给控制器的Kendo DateTimePicker日期的格式

连接多个字符串,发送给控制器?

如何使用href提交表单并将隐藏值发送给控制器

验证之后和发送给控制器之前,修改请求数据

我应该使用哪种语法发送给控制器的对象?

通过用户属性将Firebase Cloud Messaging通知发送给用户

自定义单元格Segue将数据发送到Second View控制器不起作用

自定义控制器动作

PHP WebSocket ZMQ-聊天操作-将数据发送给特定用户