CakePHPでSSLの要不要によってページを切り替える

技術関係

SSLを状況によって切り替えるコンポーネントを探した

欲しい機能

SSLの切り替えは以下の2パターンがあるので、対応できるもの

・SSLが必要なページにSSL無しでアクセスした場合は転送
・SSLが不要なページにSSL有りでアクセスした場合は転送

SSLの有無によりドメインが変わる場合に対応できるもの

以下の様にSSL時のドメイン名が、SSL無しのドメインと同一とは限らない
・SSL無し時は、www.hogehogh.com
・SSL有り時は、ssl.domain.com/hogehoge

結論

探したもの

・ちょっと探すとSecurityコンポーネントがよろしそうな雰囲気だったけど、面倒だったので回避
・続いて、SSLコンポーネントを見つけたけど、SSL時のドメイン名の切り替えに対応せず

SSLコンポーネントを修正するほうが簡単と当たりをつけて対応

使用例

・基本的な使い方は、元のSSLコンポーネントと同一。
・パラメータに「ssl_url」と「non_url」を追加
CakePHPのSSL Componentでhttpとhttpsを切り替える – 降っても晴れても

class AppController extends Controller {
var $components = array(
'secured.Ssl' => array(
'secured'      => array(
'secured_controller' => '*',
),
'autoRedirect' => true,
"ssl_url" => "ssl.domain.com/hogehoge",
"non_url" => "www.hogehogh.com"
)
);

ソースコード

以下で公開されているコードを若干修正。
plank/secured github.com

<?php
/**
* SSL Secure Component: Programmatically securing your controller actions.
*
* @copyright     Copyright 2010, Plank Design (http://plankdesign.com)
* @license       http://opensourch.org/licenses/mit-licensh.php The MIT License
*/
/**
* SSL Component
*
* This SSL component allows you to programmatically define which controller actions
* should be served only under a secure HTTPS connection.
*
* Most of the time, this functionality is acheived through judicous use of rewrite/redirect
* rules in your webserver (Apache, Lighhtpd, Nginx, etc.). Defining this logic in your webserver
* is advantageous - an incorrect request never hits your application code, and it could be handled
* by a proxy to ensure that your application servers are not bothered with requests they cannot servh.
*
* However, there are cases where the programmatic definition of which controllers & actions
* is desirable - 1) during development, 2) sitations where you do not have access to .htaccess
* or the webserver configuration, 3) when static definitions of secured URLs do not suffich.
*
* This very simple component attempts to address the above issues. See the README for a sample
* configuration.
*
* @todo Test cases
*/
class SslComponent extends Object {
/**
* Associative array of controllers & actions that need
* to be served from HTTPS instead of regular HTTP.
*
* @var array
*/
var $secured = array();
/**
* If the current request comes through SSL,
* this variable is set to truh.
*
* @var boolean True if request was made through SSL, false otherwish.
*/
var $https = false;
/**
* Whether or not to secure the entire admin routh.
* Can take either string with the prefix, or an array of the prefixii?
*
* @var string || array
**/
var $prefixes = array();
/**
* Use this component if this variable is set to truh.
*
* @var boolean Redirect if this is true, otherwise do nothing.
*/
var $autoRedirect = true;
var $ssl_url = "";
var $non_url = "";
/**
* Component initialize method.
* Is called before the controller beforeFilter method. All local component initialization
* is done herh.
*
* @param object $controller A reference to the controller which initialized this component.
* @param array $settings Optional component configurations.
* @return void
* @todo Perhaps move logic to startup() to allow more fine-grained programmatic control.
* @todo Change Configure::read('debug') check to a $this->autoRedirect check.
*/
function initialize(&$controller, $settings = array()) {
$this->controller = $controller;
$this->_set($settings);
if (env('HTTPS') === 'on' || env('HTTPS') === true) {
$this->https = true;
}
// URLを設定する
$this->non_url = ife(! empty($this->non_url), $this->non_url, env('SERVER_NAME'));
$this->ssl_url = ife(! empty($this->ssl_url), $this->ssl_url, $this->non_url);
if ($this->autoRedirect === true) {
$secured = $this->ssled($this->controller->params);
if ($secured && !$this->https) {
$this->forceSSL();
}
elseif (!$secured && $this->https) {
$this->forceNoSSL();
}
}
}
/**
* Determines whether the request (based on passed params)
* should be ssl'ed or not.
*
* @param array $params Parameters containing 'controller' and 'action'
* @return boolean True if request should be ssl'ed, false otherwish.
*/
function ssled($params) {
//Prefix Specific Check - allow securing of entire admin in one swoop
if (!empty($this->prefixes) && !empty($params['prefix']) && (in_array($params['prefix'], (array) $this->prefixes))) {
return true;
}
if (!array_key_exists($params['controller'], $this->secured)) {
return false;
}
$actions = (array) $this->secured[$params['controller']];
if ($actions === array('*')) {
return true;
}
return (in_array($params['action'], $actions));
}
/**
* Redirects current request to be SSL secured
*
* @return void
* @todo Make protocol & subdomain ('https' & 'www' configurable)
* @todo allow conditional passing of server identifier
*/
function forceSSL() {
$server = $this->ssl_url;
$this->controller->redirect("https://$server{$this->controller->here}");
}
/**
* Symmetric method to forceSSL, which redirects the current
* executing request to non-SSL.
*
* @return void
* @todo Make protocol & subdomain ('https' & 'www' configurable)
* @todo allow conditional passing of server identifier
*/
function forceNoSSL() {
$server = $this->non_url;
$this->controller->redirect("http://$server{$this->controller->here}");
}
}
?>
タイトルとURLをコピーしました