![](/img/trans.png)
[英]Rails: allow download of files stored on S3 without showing the actual S3 URL to user
[英]Rails 6 - Allow/Disallow file download as per user role for files on AWS S3
我有一個 Rails 6 應用程序,注冊用戶(所有者)可以在 S3 上上傳文件 -圖像/視頻,然后所有者可以向其他用戶提供訪問權限(邀請)以查看他們上傳的內容。
有沒有辦法可以限制文件訪問,以便只有所有者才能下載他上傳的文件(圖像/視頻),從而對其他非所有者/受邀用戶施加限制。 . 視頻/圖像不應僅通過右鍵單擊並輕松保存/下載它們來下載。
注意- 上傳的文件還包括大型視頻(mp4 和 HLS 流媒體),因此其他受邀用戶可以查看它們但不能下載它,除非他們是所有者/上傳者,因為文件來自 AWS Cloudfront 的視頻和 S3,如果他們是圖像。
關聯的設置如下 -
User has one role
User has many images/videos, each residing in his own folder on s3(`bucket/user_id/image_slug/` or `bucket/user_id/video_slug/`)
User has many invitations(must be view only access to owners file)
不確定,什么是正確的方法,可以是 -
讓我知道最適合這種方法的邏輯是什么。
您要實現的目標需要在多個層面上打下基礎:
根據S3 安全最佳實踐,您應該在 S3 端將權限級別保持在最低限度,以便應用程序提供預期的行為。
S3 允許您授予對用戶特定文件夾的訪問權限。
您應該查看授予訪問權限的 gem以涵蓋服務器端限制。 您還應該查看客戶端限制。 一種常見的技術是禁用鼠標右鍵單擊。
有關的:
一個可能的選擇是為您的 s3 對象生成簽名的 url,並在您的 rails 應用程序中具有“授權”邏輯。 這應該是 ActiveStorage 的默認設置,否則如果您使用 Carrierwave,則需要設置 fog_public = false
選項1:
在顯示下載文件按鈕的視圖中:
- if user.can_access_document?(document)
= link_to 'View', document.attachment_url, target: :blank
- else
Request an invite from the owner
在您的用戶 model 中:
class User < ApplicationRecord
has_many :invitations
...
def can_access_document?(document)
# Check if there is an invitation entry for this user to access said file
self.invitations.where(document_id: document.id).any?
end
end
選項 2
您還可以讓按鈕點擊特定端點/路由到您的控制器之一,例如Files#download_file
,然后在那里進行檢查並重定向到 s3 文件。
class FilesController < ApplicationController
def download
document = Document.find(params[:id])
if current_user.can_access_document?(document)
redirect_to document_url
else
raise "You don't have access to this document"
end
end
end
在您看來,只需將鏈接指向您的新 controller
= link_to 'View', download_files_url(document), target: :blank
由於文件的 url 已簽名,用戶將需要單擊您網站上的按鈕,並且不能一遍又一遍地使用相同的 url。 這些簽名的 url 也可以有一個動態的過期時間,例如,如果鏈接設置為 60 秒后過期,如果用戶在 60 秒后點擊下載文件,他/她將顯示一個 s3 錯誤,說明鏈接已過期,如下所示:
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<Expires>2018-06-28T07:13:14Z</Expires>
<ServerTime>2018-08-06T20:03:02Z</ServerTime>
<RequestId>87E1D2CFAAA7F9A6</RequestId>
<HostId>
A9BEluTV2hk3ltdFkixvQFa/yUBfUSgDjptwphKze+jXR6tYbpHCx8Z7y6WTfxu3rS4cGk5/WTQ=
</HostId>
</Error>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.