2011-12-28 105 views
4

我有一個網站,其中有一個公共和私人區域。私人區域 應通過HTTPS提供。我想將一次重定向到一個明確的HTTPS網址,然後使用相對URL來確保所有鏈接都是安全的。當用戶註銷時,我將顯式鏈接到絕對不安全的HTTP URL。Codeigniter重定向不保留HTTPS在相對重定向

我的登錄表單通過常規HTTP顯示爲不安全的網站。我的登錄表單發佈到https://www.mysite.com/login/validate,使用安全連接加載。

我的日誌顯示Apache正在通過HTTPS加載URL,codeigniter正在正確地進行驗證。

在我的控制器功能結束後,我使用CodeIgniter的URL助手的redirect方法將其重定向到/myaccount,並使用相對URL。

redirect('/myaccount'); 

這會導致codeigniter重定向到非HTTPS URL。

我的配置BASE_URL非HTTPS:

$config['base_url'] = "http://www.mysite.com" 

這是因爲網站的某些部分是安全的,而有些則沒有。

有沒有辦法告訴CodeIgniter在做相對重定向時保留HTTPS?爲什麼假設我想要轉到非HTTPS站點(如果當前控制器是通過HTTPS加載的並且我正在執行相對重定向)?

我希望的行爲是,如果我正在做相對重定向,它應該保留當前請求加載的協議。相反,它切換到配置base_url定義的內容,即使是相對重定向。

回答

16

使用此:

$config['base_url'] = "http".((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "s" : "")."://".$_SERVER['HTTP_HOST'].str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']); 

取而代之的是:

$config['base_url'] = "http://www.example.com" 

這將始終重定向到您想要的位置。你甚至不需要輸入你的域名,只需使用它就可以了!


除了上述,我也自動加載這個助手:

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

function is_https_on() 
{ 
    return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'; 
} 

function use_ssl($turn_on = TRUE) 
{ 
    $url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']; 

    if ($turn_on) 
    { 
     if (! is_https_on() && $_SERVER['HTTP_HOST'] != 'localhost') 
     { 
      redirect('https://' . $url, 'location', 301); 
      exit; 
     } 
    } 
    else 
    { 
     if (is_https_on()) 
     { 
      redirect('http://' . $url, 'location', 301); 
      exit; 
     } 
    } 
} 

/* End of file https_helper.php */ 
/* Location: ./application/helpers/https_helper.php */ 

有了這個地方,我可以把我的個人網頁始終使用HTTPS/HTTP(無論是在一個單一的方法我的控制器,或者 - 如果我想讓它影響整個控制器) - 在構造函數中)。

我簡單地使用:

use_ssl(); 

在腳本的開頭,以確定它是通過HTTPS加載。

或者,如果我只希望通過HTTP服務的話,我會用:

use_ssl(FALSE); 
+0

我真的很喜歡這個答案。我遇到了同樣的問題,並且我正在對某些幫助器(如helper和form helper中的form_open)進行擴展以正確檢測http和https,但我認爲這樣可以處理所有內容,而無需擴展多個幫助器。不知道爲什麼這樣的東西沒有內置到框架中,考慮了使用安全和非安全頁面的網站的流行程度。 – somomomo 2012-01-04 21:49:38

+0

這工作得很好!我只想補充說,一旦創建了這個幫助器,你可以自動加載它在config/autoload.php文件中。 ''''autoload ['helper'] = array('url','html','https_helper');' – cfnerd 2015-06-24 14:47:38

2

沒有「開箱即用」的方式在CI來處理這個HTTPS/HTTP切換。你可以做的是創建一個小助手(你自動包含),它會添加一個像secure_url()這樣的函數,並且很簡單地返回一個base_url,但https格式。

你將不得不效仿redirect功能也許secure_redirect()

+1

我喜歡這個答案,因爲通過自動設置'base_url','redirect()'方法取決於URL。使用額外的方法,您可以根據您需要執行的操作,重定向到/來自安全/不安全的URL。 – birderic 2011-12-28 15:53:59

-1

你可以使用一個協議相關的網址它將保持在CI中的鏈接的持久性。

中,而不是你的config.php

$config['base_url'] = 'http://example.com/'; 

放;

$config['base_url'] = '//example.com/'; 

有關協議相關鏈接的信息here

我已經在ie11,chrom(e | ium),firefox,midori上使用CI表單庫和基本鏈接對此進行了測試。所有的瀏覽器都遵守這個規範,我已經看到這個在野外使用沒有問題。

另外CI版本3的is_https功能內置在 你應該能夠簡單地使用is_https在你的控制器(例如,在結構)和重定向如果沒有使用https,則期運用上述方法保持HTTP或HTTPS不恆定的重定向。

例如,以保持整個控制器爲HTTPS,插入到你的控制器:

public function __construct() 
{ 
    parent::__construct(); 
    $this->load->helper('url'); 
    if(! is_https()){ 
     redirect('https:'.base_url('/page')); 
    } 
    //!! $conig['base_url'] must be protocol-relative 
}