1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add Authenticated Controllers example to Active Storage guide [skip ci]

The default Active Storage controllers are publicly accessible by
default.  The generated URLs are hard to guess, but anyone that knows
the blob URL will be able to download it.

The guides warn about this and advice implementing your own
authenticated controllers if required. But currently there is no
guidance on how to implement this.

This commit adds an example, based on the following comment:
https://github.com/rails/rails/pull/38843#issuecomment-619083761

The original warning mentioned 'the URLs being public'. To avoid
confusion with the S3 URL, which are only public for 5 minutes, the
warning has be changed to 'the controllers being public'.

The warning has also been moved up, to make it clear it applies to all
redirect and proxy URLs.
This commit is contained in:
Petrik 2021-06-15 21:36:20 +02:00
parent 68a695212e
commit 3152c01b2e

View file

@ -537,6 +537,11 @@ Serving Files
Active Storage supports two ways to serve files: redirecting and proxying.
WARNING: All Active Storage controllers are publicly accessible by default. The
generated URLs are hard to guess, but permanent by design. If your files
require a higher level of protection consider implementing
[Authenticated Controllers](active_storage_overview.html#authenticated-controllers).
### Redirect mode
To generate a permanent URL for a blob, you can pass the blob to the
@ -555,14 +560,6 @@ indirection decouples the service URL from the actual one, and allows, for
example, mirroring attachments in different services for high-availability. The
redirection has an HTTP expiration of 5 minutes.
WARNING: The URLs generated by Active Storage are hard to guess, but publicly
accessible by default. Anyone that knows the blob URL will be able to download it,
even if a `before_action` in your `ApplicationController` would otherwise
require a login. If your files require a higher level of protection consider
implementing your own authenticated
[`ActiveStorage::Blobs::RedirectController`](ActiveStorage::Blobs::RedirectController) and
[`ActiveStorage::Representations::RedirectController`](ActiveStorage::Representations::RedirectController)
To create a download link, use the `rails_blob_{path|url}` helper. Using this
helper allows you to set the disposition.
@ -583,8 +580,6 @@ Rails.application.routes.url_helpers.rails_blob_path(user.avatar, only_path: tru
[ActionView::RoutingUrlFor#url_for]: https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for
[ActiveStorage::Blob#signed_id]: https://api.rubyonrails.org/classes/ActiveStorage/Blob.html#method-i-signed_id
[ActiveStorage::Blobs::RedirectController]: (https://github.com/rails/rails/blob/main/activestorage/app/controllers/active_storage/blobs/redirect_controller.rb)
[ActiveStorage::Representations::RedirectController]: (https://github.com/rails/rails/blob/main/activestorage/app/controllers/active_storage/representations/redirect_controller.rb)
### Proxy mode
@ -641,6 +636,45 @@ and then generate routes like this:
<%= cdn_image_url(user.avatar.variant(resize_to_limit: [128, 128])) %>
```
### Authenticated Controllers
All Active Storage controllers are publicly accessible by default. The generated
URLs use a plain [`signed_id`][ActiveStorage::Blob#signed_id], making them hard to
guess but permanent. Anyone that knows the blob URL will be able to access it,
even if a `before_action` in your `ApplicationController` would otherwise
require a login. If your files require a higher level of protection, you can
implement your own authenticated controllers, based on the
[`ActiveStorage::Blobs::RedirectController`](ActiveStorage::Blobs::RedirectController) and
[`ActiveStorage::Representations::RedirectController`](ActiveStorage::Representations::RedirectController)
To only allow an account to access their own logo you could do the following:
```ruby
# config/routes.rb
resource :account do
resource :logo
end
```
```ruby
# app/controllers/logos_controller.rb
class LogosController < ApplicationController
# Through ApplicationController:
# include Authenticate, SetCurrentAccount
def show
redirect_to Current.account.logo.url
end
end
```
```erb
<%= image_tag account_logo_path %>
```
[ActiveStorage::Blobs::RedirectController]: (https://github.com/rails/rails/blob/main/activestorage/app/controllers/active_storage/blobs/redirect_controller.rb)
[ActiveStorage::Representations::RedirectController]: (https://github.com/rails/rails/blob/main/activestorage/app/controllers/active_storage/representations/redirect_controller.rb)
Downloading Files
-----------------