32

Ruby on Railsサイトを管理していますが、httpsプロトコルを使用して相対URLへのリダイレクトを実行する方法について混乱しています。

httpを使用して相対URLへのリダイレクトを正常に作成できます。次に例を示します。

redirect_to "/some_directory/"

しかし、httpsプロトコルを使用してURLへのリダイレクトを作成する方法を識別できません。私は絶対URLを使用することによってのみそうすることができました、例えば:

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

コードをクリーンに保ちたいので、相対URLを使用するのは良い考えのようです。Railsでこれを実現する方法を知っている人はいますか?

4

10 に答える 10

39

このActionController::Base#redirect_toメソッドはオプションハッシュを取ります。そのパラメーターの1つは、次の:protocol呼び出しを可能にするものです。

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

オプションの詳細については、#redirect_toおよびの定義を参照してください。#url_for


または、特にSSLをすべてのコントローラーアクションに使用する場合は、を使用してより宣言的なアプローチをとることができますbefore_filter。ではApplicationController、次のメソッドを定義できます。

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

次に、SSLを必要とするアクションを持つコントローラーにフィルターを追加できます。例:

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

または、アプリ全体でSSLが必要な場合は、次の場所でフィルターを宣言しますApplicationController

class ApplicationController
    before_filter :redirect_to_https
end
于 2009-11-03T00:03:28.280 に答える
34

アプリケーション全体をhttps経由で提供する場合、Rails 4.0以降、これを行うための最良の方法は、force_ssl次のように構成ファイルで有効にすることです。

# 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

デフォルトでは、このオプションはconfig/environments/production.rb新しく生成されたアプリにすでに存在しますが、コメントアウトされています。

コメントにあるように、これはhttpsにリダイレクトするだけでなく、Strict-Transport-Securityヘッダー(HSTS)を設定し、すべてのCookieにセキュアフラグが設定されていることを確認します。どちらの方法でも、重大な欠点なしにアプリケーションのセキュリティが向上します。を使用しActionDispatch:SSLます。

HSTSの有効期限設定は、デフォルトで1年に設定されており、サブドメインは含まれていません。これは、ほとんどのアプリケーションでおそらく問題ありません。hstsこれは、次のオプションで構成できます。

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

Rails 3(> = 3.1)を実行している場合、またはアプリケーション全体でhttpsを使用したくない場合はforce_ssl、コントローラーでこのメソッドを使用できます。

class SecureController < ApplicationController
  force_ssl
end

それで全部です。コントローラごと、またはで設定できますApplicationControllerifおなじみのオプションまたはunlessオプションを使用して、条件付きでhttpsを強制できます。例えば:

# Only when we're not in development or tests
force_ssl unless: -> { Rails.env.in? ['development', 'test'] }
于 2014-10-15T12:06:17.937 に答える
11

ssl_requirementリンクまたはリダイレクトがhttpsを使用しているかどうかにかかわらず、使用する方が適切であり、気にしない方がよいでしょう。ssl_requirementを使用して、SSLを必要とするアクション、SSLに対応しているアクション、およびSSLを使用しないように要求されているアクションを宣言します。

Railsアプリの外部にリダイレクトする場合は、Ollyが提案するようにプロトコルを指定すると機能します。

于 2009-11-03T02:38:04.967 に答える
3

コントローラで生成されたURLのプロトコルをグローバルに制御する場合は、アプリケーションコントローラのurl_optionsメソッドをオーバーライドできます。次のように、rails envに応じて、生成されたURLのプロトコルを強制できます。

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

この例はRails3.2.1で機能しますが、以前のバージョンまたは将来のバージョンについては正確にはわかりません。

于 2012-03-06T11:19:46.000 に答える
3

この回答は元の質問にいくらか接していますが、他の人が私と同じような状況でここにたどり着いた場合に備えて記録します。

httpsすべてのリクエストの発信元が暗号化されていなくても、RailsでURLヘルパーなどでprotoを使用する必要がある状況がありました( http)。

現在、通常、この状況(Railsがリバースプロキシやロードバランサーなどの背後にある場合は正常です)では、x-forwarded-protoヘッダーはリバースプロキシなどによって設定されるため、プロキシとRailsの間でリクエストが暗号化されていなくても(おそらくお勧めできません)ちなみに本番環境では)railsはすべてがにあると考えていますhttps

ngroktlsトンネルの背後を実行する必要がありました。指定したletsencrypt証明書を使用してngrokにtlsを終了させたいと思いました。ただし、その場合、ngrokは、設定を含むヘッダーをカスタマイズする機能を提供しませんx-forwarded-proto(ただし、この機能は将来のある時点で計画されています)。

解決策は非常に単純であることが判明しました。Railsは、オリジンのプロトコルまたはx-forwarded-proto直接設定されているかどうかに依存せず、Rackenvvarに依存しますrack.url_scheme。したがって、開発中にこのRackミドルウェアを追加する必要がありました。

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

  def call(env)
    env['rack.url_scheme'] = 'https'
    @app.call(env)
  end
end
于 2017-04-24T19:51:52.810 に答える
2

Rails 4では、force_ssl_redirectbefore_actionを使用して、単一のコントローラーにsslを適用できます。この方法を使用すると、Cookieが安全であるとマークされず、 HSTSが使用されないことに注意してください。

于 2015-04-14T10:59:22.740 に答える
2

を介してすべてのトラフィックを強制する場合https、Rails6での最良の方法は次のように構成production.rbすることです。

config.force_ssl = false

より柔軟なソリューションが必要な場合は、単純なbefore_actionフィルターを使用して処理できます。

class ApplicationController < ActionController::Base

  include SessionsHelper
  include LandingpageHelper
  include ApplicationHelper
  include UsersHelper
  include OrganisationHelper

  before_action :enforce_ssl, :except => [:health] 

  def enforce_ssl
    if ENV['ENFORCE_SSL'].to_s.eql?('true') && !request.ssl?
      redirect_to request.url.gsub(/http/i, "https")
    end
  end 


end

ヘルスチェックを使用してAWSECSFargateでアプリケーションを実行する場合、AWSターゲットグループからのヘルスチェックはhttps経由で呼び出されないため、より柔軟なソリューションが必要です。もちろん、ヘルスチェックを機能させると同時に、他のすべてのコントローラーメソッドにSSLを強制する必要があります。

これENFORCE_SSLは、この機能をオン/オフにする環境変数です。

于 2020-10-25T15:38:40.197 に答える
0

protocolに追加..._url

redirect_to your_url(protocol: 'https')

またはとsubdomain

redirect_to your_url(protocol: 'https', subdomain: 'your_subdomain')
于 2021-08-16T17:38:22.523 に答える
-2

相対URLは、定義上、現在のプロトコルとホストを使用します。使用しているプロトコルを変更する場合は、絶対URLを指定する必要があります。私は正義のアドバイスを受けて、あなたのためにこれを行う方法を作成します:

def redirect_to_secure(relative_uri)
  redirect_to "https://" + request.host + relative_uri
end
于 2009-11-02T17:48:44.387 に答える
-3

を持っているクラスを開き、適切な実装を持つredirect_toメソッドを追加します。redirect_to_secure_of次に、電話します。

redirect_to_secure_of "/some_directory/"

このメソッドをlibディレクトリまたは便利な場所に配置します。

于 2009-11-02T16:30:28.060 に答える