tutorial rails imagenes active ruby-on-rails https paperclip secure-scl

ruby-on-rails - imagenes - storage rails



Asegure las URL de clips solo para páginas seguras (4)

FYI - algunas de las respuestas anteriores no funcionan con Rails 3+, porque ActionController :: Response ha quedado en desuso. Use lo siguiente:

class PaperclipS3UrlRewriter def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) if response.is_a?(ActionDispatch::BodyProxy) && headers && headers.has_key?("Content-Type") && headers["Content-Type"].include?("text/html") body_string = response.body[0] response.body[0] = body_string.gsub(''http://s3.amazonaws.com'', ''https://s3.amazonaws.com'') headers["Content-Length"] = body_string.length.to_s [status, headers, response] else [status, headers, response] end end

fin

Y asegúrese de agregar el middleware en un buen lugar en la pila (lo agregué después de Rack :: Runtime)

config.middleware.insert_after Rack::Runtime, "PaperclipS3UrlRewriter"

Estoy tratando de encontrar la mejor forma de asegurar las URL de clips, pero solo para páginas seguras.

Por ejemplo, la página de inicio, que muestra imágenes almacenadas en S3, es http://mydomain.com y la url de la imagen es http://s3.amazonaws.com/mydomainphotos/89/thisimage.JPG?1284314856 .

Tengo páginas seguras como https://mydomain.com/users/my_stuff/49 que tienen imágenes almacenadas en S3, pero el protocolo S3 es http y no https, por lo que el usuario recibe una advertencia del navegador que dice que algunos elementos en el la página no es segura, bla, bla, bla.

Sé que puedo especificar: s3_protocol en el modelo, pero esto hace que todo sea seguro incluso cuando no es necesario. Por lo tanto, estoy buscando la mejor manera de cambiar el protocolo a https sobre la marcha, solo para páginas seguras.

Una (probablemente mala) forma sería crear un nuevo método de url como:

def custom_url(style = default_style, ssl = false) ssl ? self.url(style).gsub(''http'', ''https'') : self.url(style) end

Una cosa a tener en cuenta es que estoy usando el complemento ssl_requirement, por lo que podría haber una manera de vincularlo con eso.

Estoy seguro de que hay una forma simple y estándar de hacer esto que estoy pasando por alto, pero parece que no puedo encontrarlo.


Si alguien se topa con esto ahora: ¡hay una solución en Paperclip desde abril de 2012 ! Simplemente escribe:

Paperclip::Attachment.default_options[:s3_protocol] = ""

en un inicializador o use la opción s3_protocol dentro de su modelo.

Gracias a @Thomas Watson por iniciar esto.


Si usa Rails 2.3.xo posterior, puede usar el middleware de Rails para filtrar la respuesta antes de enviarla al usuario. De esta forma, puede detectar si la solicitud actual es una solicitud HTTPS y modificar las llamadas a s3.amazonaws.com en consecuencia.

Cree un nuevo archivo llamado paperclip_s3_url_rewriter.rb y colóquelo dentro de un directorio que se carga cuando se inicia el servidor. El directorio de lib funcionará, pero muchos prefieren crear un directorio de app/middleware y agregarlo a la ruta de carga de la aplicación Rails.

Agregue la siguiente clase al nuevo archivo:

class PaperclipS3UrlRewriter def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) if response.is_a?(ActionController::Response) && response.request.protocol == ''https://'' && headers["Content-Type"].include?("text/html") body = response.body.gsub(''http://s3.amazonaws.com'', ''https://s3.amazonaws.com'') headers["Content-Length"] = body.length.to_s [status, headers, body] else [status, headers, response] end end end

Entonces simplemente registra el nuevo middleware:

Rails 2.3.x: Agregue la línea siguiente a environment.rb al comienzo del bloque Rails::Initializer.run .
Rails 3.x: agregue la línea siguiente a application.rb al comienzo de la clase Application.

config.middleware.use "PaperclipS3UrlRewriter"

ACTUALIZAR:
Acabo de editar mi respuesta y agregué un cheque para response.is_a?(ActionController::Response) en la declaración if. En algunos casos (tal vez relacionado con el almacenamiento en caché), el objeto de respuesta es una matriz vacía (?) Y, por lo tanto, falla cuando se invoca la request .

ACTUALIZACIÓN 2: edité el ejemplo del código Rack / Middleware anterior para actualizar también el encabezado Content-Length . De lo contrario, el cuerpo HTML será truncado por la mayoría de los navegadores.


Use el siguiente código en una clase de controlador:

# locals/arguments/methods you must define or have available: # attachment - the paperclip attachment object, not the ActiveRecord object # request - the Rack/ActionController request AWS::S3::S3Object.url_for / attachment.path, attachment.options[:bucket].to_s, :expires_in => 10.minutes, # only necessary for private buckets :use_ssl => request.ssl?

Por supuesto, puede resumir esto en un método.