2012-10-29 55 views
1

我想強制某些控制器的SSL,並刪除SSL的一切。我在一個自定義的控制器類的_init()有一個片段,前一段時間,我曾希望它不工作:爲某些控制器強制使用SSL的最佳方法?

$ssl = $this->request->is('ssl'); 

$forceSecured = in_array($this->request->controller, array('Orders', 'Customers')); 

//remove SSL for non-ssl pages 
if ($ssl && !$forceSecured) { 
    return $this->redirect(Router::match(
        $this->request->params, 
        $this->request, 
        array('absolute' => true, 'scheme' => 'http://') 
      ) 
    ); 
} 

// Force ssl on for ssl pages 
if (!$ssl && $forceSecured) { 
    return $this->redirect(Router::match(
        $this->request->params, 
        $this->request, 
        array('absolute' => true, 'scheme' => 'https://') 
      ) 
    ); 
} 

我支持遺留應用程序,所以我有多個硬盤已編碼的路線已定義。我確信我可以在Router :: connect中使用一個處理程序,但我寧願對所有請求進行檢查。延續路線是否會成爲這裏的路?

回答

3

兩件事情:(1)你不能從_init()返回Response對象(這是什麼redirect()回報),和(2)你有一個微妙的設計問題。我建議做這樣的:

protected $_secure = false; 

public function __invoke($request, $params, array $options = array()) { 
    if (!$this->_secure && !$request->is('ssl')) { 
     return parent::__invoke($request, $params, $options); 
    } 
    return $this->redirect(Router::match($request->url, $request, [ 
     'absolute' => true, 'scheme' => 'https://' 
    ])); 
} 

觀察:

  • 你重定向到相同的URL,但該協議,在冗餘產生的URL沒有點
  • 的決定一個特定的控制器是否被重定向與控制器共存;因爲你到了點(你可能去點),它不只是每個控制器,但每次動作
+0

返回'Response'對象是我陷入困境的地方。另外,我想我沒有把它抽象出來。 注意,'$ this-> redirect line'缺少一個右括號。 –

+0

那裏,我修好了。 –

0

爲什麼讓它進入應用程序?如果您正在使用特定路由強制ssl,請使用htaccess重寫。

Ssl是一個傳輸協議細節,與您的站點代碼無關,讓apache(或nginx)處理這些細節。將責任分離到最好的處理事物。

如果您提供的網址EXAC你想趕上我相信有人爲可以與重寫條件邏輯幫助

+1

我同意這種說法有點,但想想鏈接生成這個變得更重要和反向路由。應用程序輸出重定向或http鏈接時效率不高,這些重定向或http鏈接必須由Web服務器再次重定向。 – rmarscher

+0

@rmarscher當應用程序發出30x重定向時,它仍然是另一個請求往返。我說完全切斷應用程序,並讓它由apache完成,然後應用程序纔看到它永遠不會路由它。 – Ray

+0

不同意。是否確保頁面的決定是一項商業決策。 (1)重寫規則不提供能夠用商業術語表達的抽象,(2)你已經有了一個業務邏輯的地方:控制器;爲什麼把它分開?您談論的優化級別很少是一個有效的關注點。 –

相關問題