假設(希望)您已升級到Rails的支持的版本,這是一個簡單的方法來實現默認的非SSL除非force_ssl
聲明。這是在ActiveSupport::Concern
形式:
module ForceNoSSL
extend ActiveSupport::Concern
ACTION_OPTIONS = [:only, :except, :if, :unless]
def force_no_ssl_redirect
if request.ssl?
options = {
:protocol => 'http://',
:host => request.host,
:path => request.fullpath,
:status => :moved_permanently
}
redirect_to ActionDispatch::Http::URL.url_for(options)
end
end
class_methods do
def force_ssl(options = {})
super
action_options = options.slice(*ACTION_OPTIONS)
skip_before_action :force_no_ssl_redirect, **action_options
end
def force_no_ssl
before_action :force_no_ssl_redirect
end
end
end
在你ApplicationController
你那麼:
include ForceNoSSL
force_no_ssl
工作原理是,默認情況下所有行動將運行force_no_ssl_redirect
回調。如果它已經是非ssl連接,則不會執行任何操作,否則請求將被重定向到http://
。
但是,如果您聲明瞭force_ssl
,則將跳過force_no_ssl_redirect
回調(僅限於由ACTION_OPTIONS
指定的操作)。
您可以擴展此以允許force_no_ssl
接受URL選項等等,就像force_ssl
動作所做的那樣,但對於我的用例來說,這不是必需的。
P.S.很多此代碼來自ActionController::ForceSSL
,因此請檢查以瞭解更多信息。
我試圖使用它,但它迫使我改變request.ssl來添加一個問號(正如有人在其他頁面上回答了這個問題)。當我去到我的force_ssl頁面時,我收到一個錯誤,說有太多的重定向 – yellowreign
太多的重定向意味着它被困在一個循環中。如果你離開before_filter會發生什麼?即使沒有請求,所有頁面都通過SSL提供服務嗎? – kakubei
不,默認情況下不是。會發生什麼情況是有人轉到https(force_ssl)頁面,並且通過鏈接訪問的所有後續頁面都採用https。我決定你是正確的讓這些頁面在https中呈現而不是強制http – yellowreign