Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 347 Vote(s) - 3.46 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How can I protect the content of public/ in a Rails app

#1
I'm maintaining a Rails app that has content in the public/ folder that will now need to be protected by a login. We're considering moving those folders of files into a path outside of public/ and writing a Rails controller to serve up the content.

Before we begin writing this, I was curious if anyone else has ran into this sort of problem? I looked for some gems / plugins that might already do this but didn't find anything. Has anyone created a gem for this?
Reply

#2
AFAIK, X-SendFile is not supported by nginx. Nginx has its own extension allowing this, called X-Accel-Redirect.

You will find more information about this here :

[To see links please register here]


There is also a rails plugin implementig this feature, on github: [goncalossilva/X-Accel-Redirect][1]


[1]:

[To see links please register here]

Reply

#3
**Making the file available at an unpredictable URL** is a simple solution currently used in some production systems.

E.g.: GitLab. The following image was uploaded to an issue of a private repository,

[To see links please register here]

, but you can still see it:

![](

[To see links please register here]

)

Note the unguessable `90574279de` prefix automatically added to the URL.

Bitbucket (non-Rails) also uses this technique.
Reply

#4
I've done this on a site where people pay to download certain files, and the files are stored in `RAILS_ROOT/private`. The first thing to know is that you want the web server to handle sending the file, otherwise your app will be held up transmitting large files and this will quickly bring your site to a halt if you have any kind of download volume. So, if you need to check authorization in a controller, then you also need a way to pass control of the download back to the web server. The best way of doing this (that I know of) is the X-Sendfile header, which is supported by Nginx, Apache (with module), and others. With X-Sendfile configured, when your web server receives a `X-Sendfile` header from your app, it takes over sending the file to the client.

Once you have X-Sendfile working for your web server, a private controller method like this is helpful:

##
# 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

Then your controller action could look something like this:

##
# 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

Obviously your authorization method will vary and you'll need to change the headers if you're offering files other than PDFs or you want the file to be viewed in the browser (get rid of `application/force-download` content type).
Reply

#5
If you want to tie content delivery with your Rails authentication and authorization system, then you essentially have to put the content behind a controller.

If you are looking at a more simple login approach, you can handle it with HTTP Auth and settings in your hosting environment (using htaccess, for example).
Reply

#6
You could use Amazon S3. You could use the controllers to generate and serve up the urls behind your secure area, and it also has a feature that basically makes resources available only for a certain amount of time once a url is generated.

Check out this url:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through