スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[CakePHP] 特定のアクションを https: によるアクセスに限定にする方法

CakePHPアプリにおいて、例えばログインなどの画面に対して https: でのアクセスを強制したい場合がある。

標準コンポーネントのひとつ、SecurityComponent を使うと、それが実現できるということが分った。

ちなみに、SecurityComponent では、GETではなくPOSTでのアクセスを強制させるとか、
その他いくつかのアクセス手段を強制することができるようだ。



最低限の使い方としては、これだけだ。

class UsersController extends AppController {
var $components = array('Security', ...その他のコンポーネント);

function beforeFilter() {
parent::beforeFilter();

// https: でなかった場合に呼ばれるメソッドを登録
$this->Security->blackHoleCallback = '_forceSecure';

// https: 強制したいアクションを指定
$this->Security->requireSecure('login', 'edit');
}

// https: でない場合に呼ばれる。
// $param には "secure" という文字列が入ってくる。requireSecure() 以外の制限も設定した場合は、
// どの条件に引っかかったのか、この文字列で判断できる。
function _forceSecure($param) {
// 404 エラーにしてしまうという方針もあるが、
// ここでは同じURLにリダイレクトして https: でアクセスするようにしている。
// ちなみに、$this->Security->blackHoleCallback = '_forceSecure'; の登録を
// 行わなければ、自動的に 404 エラーにしてくれるようだ。
$this->redirect('https://' . env('SERVER_NAME') . $this->here);
}
}


Security->requireSecure() のパラメータを指定しないと、コントローラ全体に対して
https: が強制されるようだ。


おしまい。
スポンサーサイト

[CakePHP] 各 view で共通の処理を書きたい場合

CakePHPアプリにおいて、いくつかの view で共通の処理を書きたい場合、アプリ独自の "Helper" を作って、
そこに共通処理を書くと良い。


例えば、https:// なリンクタグを吐き出す独自ヘルパを書くなら、次のようにする。
ソースファイルは app/views/helpers/html_ex.php に置く。


【標準HtmlHelperから派生する方法】

App::import('Helper', 'Html');

class HtmlExHelper extends HtmlHelper {

function secureUrl($url) {
return str_replace('http://', 'https://', parent::url($url, true));
}
function secureLink($label, $url) {
return parent::link($label, self::secureUrl($url));
}
}




【標準HtmlHelperに委譲する方法】

class HtmlExHelper extends AppHelper {

var $helpers = array('Html');

function secureUrl($url) {
return str_replace('http://', 'https://', $this->Html->url($url, true));
}
function secureLink($label, $url) {
return $this->Html->link($label, self::secureUrl($url));
}
}




これを使う側としては、例えば app_controller.php で以下のように書く。

class AppController extends Controller {

function beforeFilter() {
$this->helpers[] = 'HtmlEx';
}
}


これにより、.ctp 内で、$this->HtmlEx->secureLink('/hoge'); などと書ける。



上記の例では、標準 HtmlHelper に関わる機能だったので、HtmlHelper を使っているのだけど、
標準機能とは全く関係ない、独自処理を書きたい場合は単に以下のようなもので良い。


class HogeHelper extends AppHelper {
function hogeHoge($param) {
// do something
}
}

[CakePHP]Configure::write('debug', 0) を設定した場合に "The requested address '/' was not found on this server" となってしまう件

とりあえず開発中の CakePHP プロジェクトで、デバッグモードを製品リリース時のモードに変更してみたところ、うんざりするほどハマってしまい、かなりの時間を無駄に費やしてしまったため、メモしておく。

ちなみに、CakePHPのバージョンは1.3.9 。
で、CakePHP 全体を、apache のデフォルトドキュメントルート以下のサブフォルダに配置している。
例えばこのようにしている。

/var/www/html/myproject


http://localhost/myproject/ にアクセスすると、サイトのトップページが表示される。
といっても、CakePHP のデフォルトページである home.ctp をコピーしたものが表示されるだけなのだが。
後で、このコピーをいじって、自分のプロジェクト用に変更しようと思っていたのだ。



CakePHP の app/config/core.php で以下のようにデバッグモードをゼロ(productionレベル)にすると、トップページにアクセスした時に
"The requested address '/' was not found on this server"
というエラーになってしまう。

Configure::write('debug', 0);




検索して調べた限りでは、原因として以下のようなことが考えられると書かれていたが、
私のケースでは全て当てはまらなかった。

(1) app/tmp フォルダに書き込み権限がない。
(2) apache の mod_rewrite設定が正しく機能していない。
(3) app/tmp/cache フォルダ内にキャッシュが残っていて、それが悪影響を及ぼしている。
  キャッシュを全て消すと直る。
(4) app/config/database.php 内のデータベース設定が正しくない。
  又は、そこで指定しているデータベースを作成し忘れていたり、名前が間違っている。


やむを得ず、デバッガでうまくブレークポイントが効かないなどの別のトラブルにゲッソリしつつ、ソースコードを追いかけて行ったところ、とうとう以下の個所が原因であることを突き止めた。

***** home.ctp *****

if (Configure::read() == 0):
$this->cakeError('error404');
endif;


CakePHP のデフォルトトップページの先頭に、上記のような個所がある。
デバッグモードがゼロの場合は、何とわざわざ、404 not found エラーになるようにしてあったのだ!!

くっそー。
なんという余計なことを...

というか、このファイルの中にせっかく、To change the content of this page, create: APP/views/pages/home.ctp. なんて書いてあるんだから、どうせなら、
「Configure::write('debug', 0); する場合は、独自のページを作って、$this->cakeError('error404'); の個所は削除せよ」
とでも書いておいてほしいぞ。

これは贅沢な注文なんだろうかなぁ。

CakePHP の Auth コンポーネントを使ってログイン認証機能を実現する

CakePHP の Auth コンポーネントを使って、最低限のログイン認証機能を実現するには何をすれば良いのか、それをメモしておく。

Authコンポーネントの使い方については、CakePHP の公式サイトのマニュアルにも書かれている。
http://book.cakephp.org/ja/view/1250/%E8%AA%8D%E8%A8%BC

ただ、これでは今一つ分りにくかったので、自分なりに、チュートリアル型式でまとめておくことにする。



●このメモで実現する機能

(1) 自サイトにアクセスして来たユーザーがログイン状態かどうかチェックする。
  未ログイン状態であれば、ログイン画面に転送する。
(2) 新規ユーザー登録は誰でもできる。
  ユーザーの編集や削除もできてしまう。
(3) テーブルは2つ。
  ユーザーID管理テーブルと、自サイト本来のサービスを提供するためのダミーテーブル。



●チュートリアル

(1) あらかじめテーブルを2つ作成しておく。


CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
username varchar(64) NOT NULL UNIQUE,
password varchar(64) NOT NULL,
created DATETIME,
modified DATETIME
);

CREATE TABLE hoges (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
hogename varchar(64) NOT NULL UNIQUE,
created DATETIME,
modified DATETIME
);


最初のテーブルがユーザーID管理用で、users という名称で作成しておくことにより
Authコンポーネントが自動的に認識してくれる。
また、username、password というカラムも必須。
こちらも、この名称でカラムを作っておくことでAuthコンポーネントが自動的に認識してくれる。

2番目のテーブルは、本来のサービスを提供するためのテーブルだが、ここではダミーである。


(2) bake することにより、上記2つのテーブルへのアクセスコードを生成する。

bake方法についてはこちらを参照。
http://akabanessa.blog73.fc2.com/blog-entry-131.html


これにより、users テーブル、hoges テーブルへの、レコード追加・削除・編集のための
controller、view、modelがそれぞれ作成される。

この状態ではまだ認証機能を入れていないため、誰でも自由にこれらの機能にアクセスできてしまう。


(3) ログイン画面を用意する

ディレクトリ app/views/users の中に、login.ctp ファイルを作成する。
ファイルの内容は以下のとおり。


<?php
if ($session->check('Message.auth')) {
echo $session->flash();
echo $session->flash('auth');
}

echo $form->create('User', array('action' => 'login'));
echo $form->input('username');
echo $form->input('password');
echo $form->end('Login');
?>



(4) app ディレクトリの中に、app_controller.php ファイルを作成する。
ファイルの内容は以下のとおり。


<?php
class AppController extends Controller{

// Authコンポーネントの利用を宣言する
var $components = array('Auth', 'Session'); // Not necessary if declared in your app controller

function beforeFilter() {

// この行を入れると、パスワードの暗号強度が高まる。
// ただし、一度決めたら、後で違う方式に変更することはできないので注意。
Security::setHash('sha256'); // md5 または sha1 か sha256

// この下2行は、ログインエラーメッセージ等を変更したい場合以外は必要ない。
$this->Auth->loginError = "This message shows up when the wrong credentials are used";
$this->Auth->authError = "This error shows up with the user tries to access a part of the website that is protected.";
}
}



これにより、このサイト内の全てのコントローラで、Authコンポーネントの認証機能が有効になる。


(5) users_controller.php を修正

app/controller 内にある users_controllers.php に以下のコードを追加する。


function beforeFilter() {
parent::beforeFilter();

// ユーザー追加コマンドだけは、未ログイン状態でも使用可能にするため
$this->Auth->allow('add');
}

function login() {
}

function logout() {
$this->Session->setFlash('Logout');
$this->redirect($this->Auth->logout());
}



●なんと、たったこれだけで認証のしくみが機能してしまうのだ!!

未ログイン状態で、http://example/cake/hoges/add などにアクセスしようとすると、ログイン画面に飛ばされる。
http://example/cake/users/add にアクセスして、新規ユーザー登録した後、ログインすれば、全ての機能にアクセスできるようになる。




ただし、この状態では以下のような問題点や不満点がある。
ここでは、あくまでも最低限の認証を実現するには何を書いたら良いのか、ということを示してみたのである。


(1) 誰でもユーザー一覧を見ることができてしまう。
(2) ユーザー登録画面にはパスワード確認用入力覧がほしい。
(3) ユーザー登録画面ではキャプチャを付けたい。
(4) ユーザー登録時にはメールによる認証を行いたい。



Eclipse Indigo + PDT + Xdebug で CakePHP のデバッグ

とりあえず、CentOS上のWEBサーバーと同じマシン内のEclipseで、CakePHPをデバッグしたい。
そのための設定をメモしておく。

ちなみに環境は以下のとおり。
OS:CentOS 5.6
Eclipse:Indigo 20110615(日本語化していない)
PHP:Version 5.3.3
Xdebug:2.1.1





Eclipse のサイトに逝ってみたところ、PHP用のパッケージが見当たらなかった。

ダウンロードページの下部に次のようなリンクがあった。
Looking for the Eclipse for PHP Developers Package?

このリンクの先には、次のような説明があった。

Due to lack of a package maintainer for the Indigo release there will be no PHP (PDT) package. If you would like to install PDT into your Eclipse installtion you can do so by using the Install New Software feature from the Help Menu and installing the PHP Development Tools (PDT) SDK Feature from the Eclipse Indigo Repo >> http://download.eclipse.org/releases/indigo

つまり、"Install New Software" メニューから追加しなさい、ということだ。

なので、以下の手順により、PDTを追加インストールできる。

●Eclipse Indigo に PDT を入れる

1. [Help] --- [Install New Software] を選択
2. [Work with] 覧の右の[Add]ボタンを押下。
3. [Location]覧に http://download.eclipse.org/releases/indigo を入力し、
  [Name]覧に適当な名前を入れてOKする。
4. インストール可能なプラグイン?の一覧が表示されるので、[Programming Languages]のツリーを
  開いて[PHP Development Tools(PDT) SDK Feature]をチェックする。
5. 後はそのまま[Next]ボタンを押して行けば自動的にインストールされる。



●Eclipse + PDT で Xdebug を使えるようにする

PDTを入れただけでは、interactive debug(ソースコードデバッグ?)はできない。
(ただ、PDTの設定画面を見ると "Installed Debugger" 覧に XDebugやZend Debuggerの名前が既に並んでいる。
ひょっとすると、下記の手順を行わずともデバッグできるのかもしれない)


デバッグエンジン?を別途入れる必要があるらしい。
ZendDebugger か Xdebug のいずれかを入れられるようだが、Xdebugの方が良さそうなので、Xdebugを入れることにする。

1. Xdebugをダウンロードする。
 こちら http://www.xdebug.org/download.php からダウンロードする。
 Windows版は既にバイナリが用意されているが、Linux用はソースコードからコンパイルする必要がある。
 とりあえず、現時点での最新版である、Xdebug 2.1.1 のソースコードをダウンロードする。

2. Xdebugをコンパイルする。
 コンパイル方法は Xdebug公式サイトであるこちら http://www.xdebug.org/docs/install に書かれている。

 手順だけ抜き出すと以下のようになる。
 (面倒だったのであらかじめrootになってから操作している)
 (1) ダウンロードした書庫ファイルを適当な場所に解凍する。
   #tar -xzf xdebug-2.1.1.tgz
 (2) カレントディレクトリ変更。(必要ならディレクトリ名も変更したり移動したりしておく)
   #cd xdebug-2.1.1
 (3) 以下の各コマンドをそれぞれ実行する。
   #phpize
   #./configure --enable-xdebug
   #make
   #make install
 この状態で、ファイル xdebug-2.1.1/modules/xdebug.so が出来ているはず。
 私の環境では /usr/lib/php/modules に出来ていた。


3.PHPの設定を行う。

 (1) php.iniファイル内に以下の2行を追加。
   zend_extension="/hogehoge/xdebug.so"
   xdebug.remote_enable=1
   ※追加する場所はどこが良いのか、情報が見当たらなかったので、他の extension を記述した個所のすぐ下に追加した。
   ※2行目は、リモートデバッグの予定がなければ、追加しなくてもOK。
   ※hogehogeの部分は、上記で出来上がった xdebug.so のディレクトリ名にする。
 (2) apacheを再起動する
 (3) PHPで phpinfo(); してみて、画面の下の方に Xdebug が "enabled" となっている旨の
   表記があればOK。

 ※言うまでもないかもしれないが、apache(つまりPHP)を再起動しておく。

4.PDTの設定を行う。

 (1) [Window]---[Preferences] メニューを選択。
 (2) 画面左側ツリーの[PHP]---[Debug]を選択。
 (3) [PHP Debugger]覧で[XDebug]を選択。
 (4) 画面左側ツリーの[PHP]---[PHP Executables]を選択し、[Add]ボタンを押下。
 (5) [Name]覧には適当な名前を(例えば"PHP5.3"など)入れる。
   [Executable paht]覧には PHP の実行モジュールのフルパスを入れる。
   ※私の環境では、/usr/bin/php が実行モジュールのフルパスであった。
   [PHP ini file]覧には php.ini のフルパスを入れる。(入れなくても可?)
   ※私の環境では /etc/php.ini がフルパスであった。

5.デバッグ開始してみる。

 (1) 適当なPHPプロジェクトを作り、任意の行にブレークポイントを置く。
 (2) デバッグ対象のファイルを右クリックし[Debug As]---[Debug Configurations]を選択。
 (3) 画面下の方に隠れてしまっている[URL]覧に、WEBブラウザから見た時に相当するURLを入れる。
 (4) デバッグ対象のファイルを右クリックし[Debug As]---[PHP Web Page]を選択。
 これでデバッグモードでの実行が開始される。






●ブレークポイントが効かない

と、ここまで書いたが、今のところ CakePHP のプロジェクトをデバッグできない。
こちらの方と同様、ブレークポイントで止まらないのだ。
http://mileage-techno.cocolog-nifty.com/blog/2011/03/cakephp-on-ecli.html

CakePHPでない、単なるPHPのファイルをひとつ置いたプロジェクトではブレークポイントが効く。


最終的にブレークポイントが効くようになったのだが、原因がよく分らん。
可能性としては…

1. Eclipseでプロジェクトを作る時、CakePHPの app ディレクトリを指定してしまっていた?
 appディレクトリの親ディレクトリのレベルで指定する必要がありそうだ。
 一旦プロジェクトを破棄して、作り直したらうまくいったような気もするのだ。

2.PHPソースファイルの右クリックメニュー[Debug As][Debug Configuration]の設定を一旦全て
 削除してクリーンにしてみる必要があるかもしれない。
 一度デバッグ起動すると、その設定が上記画面に残るのだが、それをクリーンしてみたら
 うまくいったような気もするのだ。

このぐらいしか変更点が思い当たらない。









ああ、それにしてもめんどくさい…
早いところコードが書きたいのに、環境構築だけでものすごく消耗するぞ。


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。