ruby-on-rails - rubyonrails - ruby on rails website
Proteger el contenido del público/en una aplicación Rails (5)
AFAIK, X-SendFile no es compatible con nginx. Nginx tiene su propia extensión que permite esto, llamada X-Accel-Redirect.
Encontrará más información sobre esto aquí: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
También hay un complemento de rieles implementando esta característica, en github: goncalossilva/X-Accel-Redirect
Estoy manteniendo una aplicación de Rails que tiene contenido en la carpeta pública / que ahora deberá estar protegida por un inicio de sesión. Estamos considerando mover esas carpetas de archivos a una ruta fuera del público y escribir un controlador Rails para entregar el contenido.
Antes de comenzar a escribir esto, tenía curiosidad si alguien más se había encontrado con este tipo de problema. Busqué algunas gemas / complementos que ya podrían hacer esto, pero no encontré nada. ¿Alguien ha creado una gema para esto?
Podrías usar Amazon S3. Podría usar los controladores para generar y servir las URL detrás de su área segura, y también tiene una función que básicamente hace que los recursos estén disponibles solo durante un cierto tiempo una vez que se genera una URL.
Echa un vistazo a esta url: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html
Si desea vincular la entrega de contenido con su sistema de autenticación y autorización Rails, entonces esencialmente debe colocar el contenido detrás de un controlador.
Si está buscando un enfoque de inicio de sesión más simple, puede manejarlo con Autenticación HTTP y configuraciones en su entorno de alojamiento (utilizando htaccess, por ejemplo).
Hacer que el archivo esté disponible en una URL impredecible es una solución simple que se usa actualmente en algunos sistemas de producción.
Por ejemplo: GitLab. La siguiente imagen se cargó en un problema de un repositorio privado, https://gitlab.com/cirosantilli/test-private/issues/1 , pero aún puede verlo:
Tenga en cuenta que el prefijo 90574279de
se puede agregar automáticamente a la URL.
Bitbucket (non-Rails) también utiliza esta técnica.
He hecho esto en un sitio donde la gente paga para descargar ciertos archivos, y los archivos se almacenan en RAILS_ROOT/private
. Lo primero que debe saber es que desea que el servidor web maneje el envío del archivo; de lo contrario, su aplicación se retrasará al transmitir archivos grandes y esto detendrá su sitio rápidamente si tiene algún tipo de volumen de descarga. Por lo tanto, si necesita verificar la autorización en un controlador, también necesita una forma de pasar el control de la descarga al servidor web. La mejor manera de hacer esto (que yo sepa) es el encabezado X-Sendfile, que es compatible con Nginx, Apache (con módulo) y otros. Con X-Sendfile configurado, cuando su servidor web recibe un encabezado X-Sendfile
desde su aplicación, se encarga de enviar el archivo al cliente.
Una vez que tenga X-Sendfile trabajando para su servidor web, un método de controlador privado como este es útil:
##
# 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
Entonces, la acción de tu controlador podría verse así:
##
# 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
Obviamente, su método de autorización variará y deberá cambiar los encabezados si está ofreciendo archivos que no sean archivos PDF o si desea que el archivo se vea en el navegador (elimine el tipo de contenido de la application/force-download
).