Codeigniter重定向在相对重定向中不保留HTTPS


Codeigniter redirect not preserving HTTPS in relative redirects

我有一个有公共和私人区域的网站。私人区域应该通过HTTPS提供。我想重定向一次到一个明确的HTTPS url,然后,使用相对url,所有的链接是安全的。当用户登出时,我将显式链接到一个绝对不安全的HTTP URL。

我的登录表单通过常规HTTP显示一个不安全的站点。我的登录表单发布到https://www.mysite.com/login/validate,它使用安全连接加载。

我的日志显示Apache正在通过HTTPS加载URL, codeigniter正在正确地进行验证。

在我的控制器功能结束时,我使用CodeIgniter的URL助手的redirect方法与相对URL重定向到/myaccount

redirect('/myaccount');

这会导致编码器重定向到非https URL。

我的配置base_url是非https:

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

这是因为网站的某些部分是安全的,而其他部分则不是。

是否有一种方法告诉CodeIgniter保存HTTPS时做相对重定向?如果当前控制器是通过HTTPS加载的,那么为什么我想去一个非HTTPS站点,而我正在做一个相对重定向?

我想要的行为是,如果我做相对重定向,它应该保留当前请求被加载的协议。相反,它会切换到配置base_url所定义的内容,甚至对于相对重定向也是如此。

使用

$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);

在CI中没有'开箱即用'的方法来处理这种HTTPS/HTTP切换。您可以做的是创建一个小的助手(您自动包含),它将添加一个功能,如secure_url(),并相当简单地返回base_url将,但https格式。

您将不得不模拟相同的redirect功能,可能作为secure_redirect()

您可以使用协议-相对url,它将在CI中保持链接的持久性。

config.php中代替:

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

把;

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

协议相关链接信息。

我已经在ie11, chrome,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
}