public/ フォルダーにコンテンツがあり、ログインによって保護する必要がある Rails アプリを維持しています。これらのファイルのフォルダーを public/ 以外のパスに移動し、Rails コントローラーを作成してコンテンツを提供することを検討しています。
これを書き始める前に、この種の問題に遭遇した人が他にいるかどうか知りたいと思いました。すでにこれを行っている可能性のある宝石/プラグインを探しましたが、何も見つかりませんでした。誰かがこのための宝石を作成しましたか?
public/ フォルダーにコンテンツがあり、ログインによって保護する必要がある Rails アプリを維持しています。これらのファイルのフォルダーを public/ 以外のパスに移動し、Rails コントローラーを作成してコンテンツを提供することを検討しています。
これを書き始める前に、この種の問題に遭遇した人が他にいるかどうか知りたいと思いました。すでにこれを行っている可能性のある宝石/プラグインを探しましたが、何も見つかりませんでした。誰かがこのための宝石を作成しましたか?
特定のファイルをダウンロードするために人々がお金を払うサイトでこれを行いました。ファイルは に保存されていRAILS_ROOT/private
ます。最初に知っておくべきことは、Web サーバーがファイルの送信を処理するようにすることです。そうしないと、アプリが大きなファイルの送信を停止し、何らかのダウンロード ボリュームがある場合、サイトがすぐに停止してしまいます。そのため、コントローラーで承認を確認する必要がある場合は、ダウンロードの制御を Web サーバーに戻す方法も必要です。これを行う最良の方法 (私が知っている) は、Nginx、Apache (モジュール付き) などでサポートされている X-Sendfile ヘッダーです。X-Sendfile が構成されている場合、Web サーバーX-Sendfile
がアプリからヘッダーを受信すると、クライアントへのファイルの送信を引き継ぎます。
Web サーバーで X-Sendfile が機能するようになったら、次のようなプライベート コントローラー メソッドが役立ちます。
##
# Send a protected file using the web server (via the x-sendfile header).
# Takes the absolute file system path to the file and, optionally, a MIME type.
#
def send_file(filepath, options = {})
options[:content_type] ||= "application/force-download"
response.headers['Content-Type'] = options[:content_type]
response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filepath)}\""
response.headers['X-Sendfile'] = filepath
response.headers['Content-length'] = File.size(filepath)
render :nothing => true
end
次に、コントローラーのアクションは次のようになります。
##
# Private file download: check permission first.
#
def download
product = Product.find_by_filename!(params[:filename])
if current_user.has_bought?(product) or current_user.is_superuser?
if File.exist?(path = product.filepath)
send_file path, :content_type => "application/pdf"
else
not_found
end
else
not_authorized
end
end
application/force-download
PDF 以外のファイルを提供する場合や、ファイルをブラウザーで表示する場合 (コンテンツ タイプを削除する場合)は、明らかに承認方法が異なり、ヘッダーを変更する必要があります。
Amazon S3 を使用できます。コントローラーを使用して、安全な領域の背後にある URL を生成して提供することができます。また、基本的に、URL が生成されると一定時間だけリソースを利用できるようにする機能もあります。
この URL を確認してください: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html
私の知る限り、X-SendFile は nginx ではサポートされていません。Nginx には、X-Accel-Redirect と呼ばれる、これを可能にする独自の拡張機能があります。
詳細については、こちらをご覧ください: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
github には、この機能を実装する Rails プラグインもあります: goncalosilva/X-Accel-Redirect
コンテンツ配信を Rails の認証および承認システムと結び付けたい場合は、基本的にコンテンツをコントローラーの背後に配置する必要があります。
より単純なログイン アプローチを検討している場合は、ホスティング環境で HTTP Auth と設定を使用して処理できます (たとえば、htaccess を使用)。
予測不可能な URL でファイルを使用できるようにすることは、現在一部の実稼働システムで使用されている単純なソリューションです。
例: GitLab. 次の画像は、プライベート リポジトリの課題https://gitlab.com/cirosantilli/test-private/issues/1にアップロードされましたが、まだ表示できます。
90574279de
推測できないプレフィックスが URL に自動的に追加されることに注意してください。
Bitbucket (Rails 以外) もこの手法を使用します。