そうだ車輪と名づけよう

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

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}");
}
}
?>