【问题标题】:How can I have CodeIgniter load specific pages using SSL?如何让 CodeIgniter 使用 SSL 加载特定页面?
【发布时间】:2010-12-02 19:11:36
【问题描述】:

如何让 CodeIgniter 使用 SSL 加载特定页面?我有一个 apache2/mode_ssl 服务器。 mod_ssl 使用与非安全页面不同的文档根目录。例如,https(端口 443)将提供来自 /var/www/ssl_html/ 的页面,而 http(端口 80)提供来自 /var/www/html/ 的页面。我怎样才能让 CodeIgniter 很好地使用这个设置?

【问题讨论】:

    标签: php apache ssl codeigniter https


    【解决方案1】:

    解决这个问题的方法很少。

    选项 1:

    我可能会将代码部署到两个文件夹,然后在文件:/system/application/config/config.php 中,将您的页面设置为:

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

    $config['base_url'] = "https://www.yoursite.com/";
    

    然后在您的非 SSL VirtualHost 文件夹中,将您的配置设置为按文件夹将受保护的页面重定向到 SSL 站点:

    RedirectPermanent /sslfolder https://www.yoursite.com/sslfolder
    

    选项 2:

    将所有内容发送到 SSL 并将所有代码保存在一个文件夹中

    /system/application/config/config.php,将你的页面设置为:

    $config['base_url'] = "https://www.yoursite.com/";
    

    其他选项

    还有一些更老套的方法可以通过 header() 重定向等来做到这一点,但我认为您不想为此选项维护不同的代码库。我不建议这样做,但您可以执行以下操作:

    $config['base_url'] = “http://” . $_SERVER['http_host'] . “/”;
    

    【讨论】:

    • 谢谢。我想我会选择第一个选项,然后重写 url_help 来处理 https。
    • 简单的答案是将$config['base_url'] 设置为空字符串,如=''; - CodeIgniter 将根据 URL 自动检测所有内容。因此,您可以任意打开任何带有或不带有 SSL 的页面,只需键入 URL。无需在服务器上的 ssl 和 non_ssl 目录之间拆分内容。
    • 仅供参考,这个$config['base_url'] = “http://” . $_SERVER['http_host'] . “/”; 是错误的,应该是$config['base_url'] = 'https://' . $_SERVER["HTTP_HOST"] . '/'; 语法错误并且$_SERVER["http_host"](小写)不存在...
    【解决方案2】:

    在 application/config/config.php 中,将 base_url 设置为:

    $config['base_url'] = ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . "://{$_SERVER['HTTP_HOST']}/";

    这将允许它在任何域上工作,如果您在本地测试,这很方便。

    【讨论】:

    • 我成功地使用了它:RewriteCond %{HTTPS} =off RewriteRule ^my-secure-url-segment https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L ] 在我的 .htaccess 文件中。
    • 对我没用, $_SERVER['SERVER_PORT'] 对我来说是 80 ; HTTP_X_FORWARDED_PORT 是 443
    【解决方案3】:

    我在 ./application/config/config.php 文件中添加了以下几行,它运行良好:

    $protocol = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) ? 'https' : 'http';
    $config['base_url'] = $protocol.'://www.yoursite.com';
    

    【讨论】:

      【解决方案4】:

      我将维护两组代码并使用 post_controller_constructor 挂钩处理强制重定向到 HTTPS 页面。该钩子将在每个页面呈现之前被调用,以检查是否应根据访问者在您网站上的当前位置将访问者重定向到 HTTPS。

      第 1 步

      创建文件:system/application/hooks/SecureAccount.php

      <?php
      
      class SecureAccount
      {
          var $obj;
      
          //--------------------------------------------------
          //SecureAccount constructor
          function SecureAccount()
          {
              $this->obj =& get_instance();
          }
      
          //--------------------------------------------------
          //Redirect to https if in the account area without it
          function index()
          {
              if(empty($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] !== 'on')
              {
                  $this->obj =& get_instance();
                  $this->obj->load->helper(array('url', 'http'));
      
                  $current = current_url();
                  $current = parse_url($current);
      
                  if((stripos($current['path'], "/account/") !== false))
                  {
                      $current['scheme'] = 'https';
      
                      redirect(http_build_url('', $current), 'refresh');
                  }
              }
          }
      }
      ?>
      

      第 2 步

      在函数中自定义路径,您网站的哪些区域应强制使用 HTTPS。

      第 3 步

      将以下内容添加到 system/application/config/hooks.php

      /* Force HTTPS for account area */
      $hook['post_controller_constructor'] = array(
                                      'class'    => 'SecureAccount',
                                      'function' => 'index',
                                      'filename' => 'SecureAccount.php',
                                      'filepath' => 'hooks',
                                      'params'   => array()
                                      );
      

      【讨论】:

        【解决方案5】:

        我可以很容易,我只定义:

        $config['base_url'] = '';
        

        CI 自动获取 base_url =D

        【讨论】:

        • 不再推荐,仅供参考。
        • 是的,config.php 中的 CI3 显示“不得在生产中使用!”
        • 这个“提示”在 2014 年左右的 CI2 上运行良好,我不知道其他 CI 版本,但我从来没有遇到过问题和警告 :)
        【解决方案6】:

        我在 config.php 中解决了问题

        $config['ssl_active'] = false;
        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) {
            $config['ssl_active'] = true;
        }
        
        $config['base_url'] = ($config['ssl_active'] === true )?"https":"http" . $_SERVER['HTTP_HOST'];
        

        目录麻烦,可以用简单的符号链接ln -s

        【讨论】:

          【解决方案7】:

          这对我有用。 我们的服务器都有 $_SERVER['SERVER_PORT']$_SERVER['HTTP_X_FORWARDED_PORT']

          我们应该首先检查 $_SERVER['HTTP_X_FORWARDED_PORT'] 是否可用,并使用它来代替 $_SERVER['SERVER_PORT']

          $config['base_url'] =
          ( ( ( empty($_SERVER['HTTP_X_FORWARDED_PORT']) ? $_SERVER['SERVER_PORT'] : $_SERVER['HTTP_X_FORWARDED_PORT'] ) == 443 ? 'https' : 'http') . "://" . $_SERVER['HTTP_HOST'] )
          . str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']) ;
          

          在我们的 linux 服务器上对此进行了测试...


          顺便说一句,这是基于斯凯勒之前的回答。

          $config['base_url'] = ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . "://{$_SERVER['HTTP_HOST']}/";
          

          【讨论】:

          • 如果 CI 部署在子目录中,之前的答案不会维护 script_name,我们需要保留它。 str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME'])
          【解决方案8】:

          我想到的解决方案是像这样使用 str_replace()

          $base_url_str = base_url(); 
          $secure_base_url = str_replace("http","https",$base_url_str );
          

          每当我需要一个安全的位置时,我都会使用 $secure_base_url 而不是 base_url(), 所以假设你的 base_url() 是 http://www.example.com 那么 $secure_base_url 将是 https://www.example.com

          【讨论】:

            【解决方案9】:

            另一个question与此类似

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

            在您的config.php 中,而不是:

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

            放;

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

            关于协议相关链接here的信息。

            【讨论】:

              【解决方案10】:

              【讨论】:

              • 在提供答案时,您应该在实际答案中包含方法/示例。如果您的链接被删除,您的回答将变得毫无用处。
              猜你喜欢
              • 1970-01-01
              • 2020-01-14
              • 2012-04-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多