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

时间:2011-12-28 14:59:28

标签: php codeigniter

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

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

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

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

redirect('/myaccount');

这会导致codeigniter重定向到非HTTPS网址。

我的配置base_url是非HTTPS:

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

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

有没有办法告诉CodeIgniter在进行相对重定向时保留HTTPS?为什么假设我想要通过HTTPS加载当前控制器并且我正在进行相对重定向,那么我想进入非HTTPS站点?

我想要的行为是,如果我正在进行相对重定向,它应该保留加载当前请求的协议。相反,它正在切换到config base_url已定义的内容,即使对于相对重定向也是如此。

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

在CI中没有“开箱即用”的方式来处理此HTTPS / HTTP切换。你可以做的是创建一个小助手(你自动包括),它将添加secure_url()之类的功能,并且很简单地返回base_url的内容,但是https格式。

您必须模拟与redirect相同的secure_redirect()函数。

答案 2 :(得分:-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
}