Pundit を使用して Refile gem でアップロードされたファイルの認証を行うにはどうすればよいですか? ファイルをアップロードしたユーザーに制限する必要があるファイルをアップロードしましたが、Refile の attachment_url が生成する URL を持つ人は誰でもファイルにアクセスできます。Refile は独自の Sinatra アプリを使用しているため、Pundit の authorize メソッドを呼び出すための Rails コントローラーはありません。
1 に答える
コントローラーでは、ファイルをダウンロードするメソッドを使用できます。download
より複雑な例として、コントローラーにアクションがあるとしましょうUsersController
。pundit
ここからは通常通りご利用いただけます。このdownload
アクションは、ユーザーの画像を取得します。
免責事項: これは、このアクションが頻繁に呼び出されるとサーバーに打撃を与えることになるため、プロダクション プラクティスの恐ろしい例です。このアクションが呼び出されるたびに、基本的に画像のサイズを変更しています。ただし、概念実証として、refile
ファイルのダウンロードが通常どのように機能するかを超えて、求めている承認を追加します。
fill オプションprocessor
を初期化する変数を作成します。ImageProcessor
次に、一時ファイルを作成し、バイナリ モードに設定します。ユーザーモデルからファイルを取得し、一時ファイルに読み込みます。一時ファイルをファイルの先頭に巻き戻し、 に読み込みますMiniMagick
。次にprocessor
、一時ファイルを変換するように要求します (元のファイルはそのまま残します)。次に、ファイルをユーザーに送信します。
def download
@user = User.find(params[:id])
authorize @user
processor = Refile.processor(:fill, Refile::ImageProcessor.new(:fill))
temp_file = Tempfile.new('profile_image')
temp_file.binmode
temp_file.write @user.profile_image.read
temp_file.rewind
image_file = MiniMagick::Image.new(temp_file.path)
file = processor.fill(image_file, 150, 150)
temp_file.close
send_file file.path
end
ファイルを次のようにレンダリングする例を次に示します。image_tag
サイズ変更してダウンロードする画像を呼び出すコードとともに。
<%= image_tag user_download_path(@user), class: 'img-circle img-thumbnail' %>
他のさまざまな処理オプションとディメンションを受け入れるようにアクションを設定できます。この例では、150x150 ピクセルのサイズを塗りつぶす方法を示しています。
より明確にするために編集します。
の機能はtemp_file
、元のイメージをそのままにしておくことです。元のファイルの未処理のダウンロードを提供するだけの場合は、次のようにすることができます。ダウンロードをカスタマイズするための 、 、 などのオプションとその処理方法についても説明しsend_file
ます。send_data
filename
disposition
content_type
def download
@user = User.find(params[:id])
authorize @user
send_file @user.profile_image.download
end
編集:ソースをさらに調べたRefile
ところ、ファイル リンクの作成は、ルート内のエンジンのマウントによって引き起こされていることがわかりました。初期化ファイルを作成し、そこに以下のコードを配置します。これにより、アップロードされたファイルへの公開リンクを削除しながら、上記の既存の機能を維持できます。
Refile.configure do |config|
# config.direct_upload = ["cache"]
# config.allow_origin = "*"
# config.logger = Logger.new(STDOUT)
# config.mount_point = "attachments"
config.automount = false
# config.content_max_age = 60 * 60 * 24 * 365
# config.types[:image] = Refile::Type.new(:image, content_type: %w[image/jpeg image/gif image/png])
end