with redirect_to rails method link_to entre diferencia ruby-on-rails redirect https relative-path

ruby-on-rails - method - render vs redirect_to rails



Rieles redirigir con https (8)

Estoy manteniendo un sitio de Ruby on Rails y estoy confundido sobre cómo realizar redirecciones a URL relativas usando el protocolo https.

Puedo crear correctamente una redirección a una URL relativa utilizando http, por ejemplo:

redirect_to "/some_directory/"

Pero no puedo discernir cómo crear una redirección a una URL usando el protocolo https. Solo he podido hacerlo al usar URLs absolutas, por ejemplo:

redirect_to "https://mysite.com/some_directory/"

Me gustaría mantener mi código limpio, y usar URL relativas parece una buena idea. ¿Alguien sabe cómo lograr esto en Rails?


Abra la clase que tiene redirect_to y agregue un método redirect_to_secure_of con una implementación adecuada. Luego llame:

redirect_to_secure_of "/some_directory/"

Pon este método en el directorio lib o en algún lugar útil.


El método ActionController::Base#redirect_to toma un hash de opciones, uno de cuyos parámetros es :protocol que le permite llamar:

redirect_to :protocol => ''https://'', :controller => ''some_controller'', :action => ''index''

Consulte la definición de #redirect_to y #url_for para obtener más información sobre las opciones.

Alternativamente, y especialmente si SSL se va a usar para todas las acciones de su controlador, puede tomar un enfoque más declarativo usando un before_filter . En ApplicationController puede definir el siguiente método:

def redirect_to_https redirect_to :protocol => "https://" unless (request.ssl? || request.local?) end

A continuación, puede agregar filtros en los controladores que tienen acciones que requieren SSL, por ejemplo:

class YourController before_filter :redirect_to_https, :only => ["index", "show"] end

O bien, si requiere SSL en toda su aplicación, declare el filtro en ApplicationController :

class ApplicationController before_filter :redirect_to_https end


En Rails 4 uno puede usar el force_ssl_redirect before_action para aplicar ssl para un solo controlador. Tenga en cuenta que al usar este método, sus cookies no se marcarán como seguras y no se usará HSTS .


Esta respuesta es algo tangencial a la pregunta original, pero la grabo en caso de que otros terminen aquí en circunstancias similares a mí.

Tuve una situación en la que necesitaba que Rails utilizara https proto en url helpers, etc. aunque el origen de todas las solicitudes no está encriptado ( http ).

Ahora, normalmente en esta situación (que es normal cuando Rails está detrás de un proxy inverso o balanceador de carga, etc.), el encabezado x-forwarded-proto es establecido por el proxy inverso o lo que sea, por lo que aunque las solicitudes no están encriptadas entre el proxy y rails (probablemente no sea aconsejable en la producción por cierto) rails cree que todo está en https .

Necesitaba correr detrás de un túnel ngrok tls. Quería que ngrok terminara los tls con los certificados de letsencrypt que especifiqué. Sin embargo, cuando lo hace, ngrok no ofrece la posibilidad de personalizar encabezados, incluida la configuración de x-forwarded-proto (aunque esta función está planificada en algún momento en el futuro).

La solución resultó ser bastante simple: Rails no depende del protocolo del origen o de si x-forwarded-proto se establece directamente, sino de Rack env var rack.url_scheme . Así que solo necesitaba agregar este middleware Rack en desarrollo:

class ForceUrlScheme def initialize(app) @app = app end def call(env) env[''rack.url_scheme''] = ''https'' @app.call(env) end end


Las URL relativas, por definición, usan el protocolo y el host actuales. Si desea cambiar el protocolo utilizado, debe proporcionar la URL absoluta. Tomaré el consejo de Justice y crearé un método que lo haga por usted:

def redirect_to_secure(relative_uri) redirect_to "https://" + request.host + relative_uri end


Probablemente sea mejor que ssl_requirement y no te ssl_requirement si un enlace o redirección está o no usando https. Con ssl_requirement, usted declara qué acciones requieren SSL, cuáles son capaces de SSL y cuáles son necesarias para no usar SSL.

Si está redirigiendo a algún lugar fuera de su aplicación Rails, entonces la especificación del protocolo como sugiere Olly funcionará.


Si desea controlar globalmente el protocolo de direcciones URL generadas en los controladores, puede anular el método url_options en su controlador de aplicaciones. Podrías forzar el protocolo de las URL generadas dependiendo del env de los raíles, así:

def url_options super @_url_options.dup.tap do |options| options[:protocol] = Rails.env.production? ? "https://" : "http://" options.freeze end end

este ejemplo funciona en Rails 3.2.1, no estoy del todo seguro para versiones anteriores o futuras.


Si desea que toda su aplicación se force_ssl en https, entonces desde Rails 4.0, la mejor forma de hacerlo es habilitar force_ssl en el archivo de configuración de la siguiente manera:

# config/environments/production.rb Rails.application.configure do # [..] # Force all access to the app over SSL, use Strict-Transport-Security, # and use secure cookies. config.force_ssl = true end

Por defecto, esta opción ya está presente en config/environments/production.rb en las aplicaciones recién generadas, pero está comentada.

Como dice el comentario, esto no solo redireccionará a https, sino que también configurará el encabezado de Strict-Transport-Security ( HSTS ) y se asegurará de que el indicador de seguridad esté establecido en todas las cookies. Ambas medidas aumentan la seguridad de su aplicación sin inconvenientes significativos. Utiliza ActionDispatch:SSL .

La configuración de expiración de HSTS está establecida en un año por defecto y no incluye subdominios, lo que probablemente sea bueno para la mayoría de las aplicaciones. Puede configurar esto con la opción hsts :

config.hsts = { expires: 1.month.to_i, subdomains: false, }

Si está utilizando Rails 3 (> = 3.1) o no quiere usar https para toda la aplicación, puede usar el método force_ssl en un controlador:

class SecureController < ApplicationController force_ssl end

Eso es todo. Puede configurarlo por controlador o en su ApplicationController . Puede forzar https condicionalmente utilizando las opciones familiares if o unless ; por ejemplo:

# Only when we''re not in development or tests force_ssl unless: -> { Rails.env.in? [''development'', ''test''] }