У меня есть сайт, который имеет общественный и частный район. Частная зона должна обслуживаться через HTTPS. Я хочу перенаправить один раз на явный HTTPS-url, а затем, используя относительные URLS, все ссылки будут защищены. Когда пользователь выйдет из системы, я буду явно ссылаться на абсолютный небезопасный URL-адрес HTTP.
Моя форма входа в систему отображается на незащищенном сайте через обычный HTTP. Мои сообщения в форме входа в систему https://www.mysite.com/login/validate
, которые загружаются с использованием безопасного соединения.
Мои журналы показывают, что Apache загружает URL-адрес через HTTPS, а codeigniter корректно выполняет свою проверку.
В конце моей функции контроллера я перенаправляю на /myaccount
используя метод redirect
URL-адреса URL-адреса CodeIgniter с относительным URL-адресом.
redirect('/myaccount');
Это приводит к тому, что codeigniter перенаправляется на URL-адрес, отличный от HTTPS.
Моя конфигурация base_url не является HTTPS:
$config['base_url'] = "http://www.mysite.com"
Это связано с тем, что некоторые части сайта являются безопасными, а другие нет.
Есть ли способ сообщить CodeIgniter о сохранении HTTPS при выполнении относительных перенаправлений? Почему предполагается, что я хочу перейти на сайт без HTTPS, если текущий контроллер был загружен через HTTPS, и я делаю относительную перенаправление?
Желаемое поведение для меня заключается в том, что если я выполняю относительное перенаправление, он должен сохранить протокол, через который был загружен текущий запрос. Вместо этого он переключается на то, что определил config 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);
Нет способа «из коробки» справиться с этой передачей HTTPS / HTTP в CI. То, что вы МОЖЕТЕ сделать, это создать небольшой помощник (который вы secure_url()
автоматически), который добавит функцию, подобную secure_url()
, и довольно просто вернет то, что будет иметь base_url
, но формат https.
Вы должны были бы эмулировать одну и ту же функцию redirect
возможно, как secure_redirect()
.
вы можете использовать URL-адрес, относящийся к протоколу, который будет сохранять постоянство при связывании в CI.
в вашем config.php
вместо:
$config['base_url'] = 'http://example.com/';
положил;
$config['base_url'] = '//example.com/';
информацию об относительных для протокола ссылках.
Я тестировал это на 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 }