web-dev-qa-db-fra.com

Rails Redirection avec HTTPS

Je maintient un Ruby sur Rails site et je suis confus sur la manière d'effectuer des redirections vers des URL relatives à l'aide du protocole HTTPS.

Je peux créer avec succès une redirection vers une URL relative à l'aide de HTTP, par exemple:

redirect_to "/some_directory/"

Mais je ne peux pas discerner comment créer une redirection vers une URL à l'aide du protocole HTTPS. Je n'ai été capable que de le faire en utilisant des URL absolues, par exemple:

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

Je voudrais garder mon code propre et utiliser des URL relatives semble être une bonne idée. Est-ce que quelqu'un sait comment y parvenir dans des rails?

28
Brian D'Astous

Vous ferez probablement mieux d'utiliser ssl_requirement et ne pas soigner si un lien ou une redirection est ou n'utilise pas https. Avec SSL_Requirement, vous déclarez quelles actions nécessitent SSL, lesquelles sont capables de SSL et lesquelles sont nécessaires pour ne pas utiliser SSL.

Si vous redirigez quelque part en dehors de votre Rails application, spécifiez le protocole comme suggère que l'olly fonctionnera.

11
Andy Gaskell

Les ActionController::Base#redirect_to La méthode prend une hachage d'options, dont l'un des paramètres est :protocol qui vous permet d'appeler:

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

Voir la définition pour #redirect_to et #url_for Pour plus d'informations sur les options.


Alternativement, et surtout si SSL doit être utilisé pour toutes vos actions de contrôleur, vous pouvez adopter une approche plus déclarative en utilisant un before_filter. Dans ApplicationController Vous pouvez définir la méthode suivante:

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

Vous pouvez ensuite ajouter des filtres dans vos contrôleurs qui ont des actions nécessitant SSL, E.G:

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

Ou, si vous avez besoin de SSL sur votre application entière, déclarez le filtre dans ApplicationController:

class ApplicationController
    before_filter :redirect_to_https
end
37
Olly

Cette réponse est quelque peu tangitienne à la question initiale, mais je l'enregistre au cas où d'autres finissent ici dans des circonstances similaires.

J'ai eu une situation où je devais avoir Rails utiliser https proto dans les aides d'URL, etc. Même si l'origine de toutes les demandes est non cryptée (http).

Maintenant, habituellement dans cette situation (qui est normal lorsque Rails est derrière un proxy inverse ou un équilibreur de charge, etc.), l'en-tête x-forwarded-proto est défini par le proxy inverse ou quoi que ce soit, même si les demandes sont non cryptées entre le Proxy & Rails (probablement non conseillé en production par la manière) Rails pense que tout est dans https.

Je devais courir derrière un tunnel Ngrok TLS. Je voulais avoir Ngrok Terminez les TLS avec les certificats de LetSenCrypt que j'ai spécifiés. Cependant, quand cela le fait, Ngrok n'offre pas la possibilité de personnaliser les en-têtes, y compris la définition x-forwarded-proto (bien que cette fonctionnalité soit planifiée à un moment donné à l'avenir).

La solution s'est avérée assez simple: Rails _ ne dépend pas non plus du protocole de l'origine ou si x-forwarded-proto est défini directement, mais sur le rack env VaR rack.url_scheme. Donc, j'ai juste besoin d'ajouter ce middleware de rack dans le développement:

class ForceUrlScheme
  def initialize(app)
    @app = app
  end

  def call(env)
    env['rack.url_scheme'] = 'https'
    @app.call(env)
  end
end
3
Michael Johnston

Si vous souhaitez contrôler globalement le protocole des URL générées dans des contrôleurs, vous pouvez remplacer la méthode URL_OPTIONS dans votre contrôleur d'application. Vous pouvez forcer le protocole des URL générées en fonction du Rails env.

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

cet exemple fonctionne dans Rails 3.2.1, je ne suis pas vraiment sûr des versions antérieures ou futures.

2
Shamu

In Rails 4 on peut utiliser force_ssl_redirect avant_action pour appliquer SSL pour un seul contrôleur. Veuillez noter qu'en utilisant cette méthode, vos cookies ne seront pas marqués comme sécurisé et [~ # ~ # ~ # ~ ~] n'est pas utilisé.

2
Samuel