Cakephpで任意のコントローラにBASIC認証をApache側でかける

Cakephp1.2.6


追記(2010/12/16)
この方法は抜け道があることが判明しました。詳細は下記をご覧ください。
http://wp.serpere.info/archives/1883
私の場合の対応方法として、members/.htaccessに下記の1行を追加し、

SetEnv MEMBER_CHECK_FLAG ok

Membersコントローラ側でその環境変数がセットされているかチェックし、されていなければエラーとする対応でいけると思います。
環境変数はcake側で下記のようにして取得可能です。

$flg = env('MEMBER_CHECK_FLAG');

追記(2010/12/16)ここまで



別にCakephp以外でも同じようにmod_rewriteでindex.phpとかを呼び出してるようなフレームワークならこの方法はいけると思います。


Basic認証はCake標準の機能で持ってますが、ちょっと使いにくい。一度間違えると次からブラウザ落とすまで再入力させてくれない(画面真っ白のまま)などの問題がありますので。PHPCGIモードで動いてる場合でも今回の方法でいけると思います(mod_rewriteは必須)
ということで、Apache側の設定でBasic認証をかけるTips。こっちのほうが慣れてるし再入力させてくれるので良いです。


例えば、/members/indexとか/members/addみたいなurlがあった場合、/members/以下の全てにBasic認証をかけるには(静的な/members/top.htmlみたいなファイルも含めて)、

1. ドキュメントルートにmembersディレクトリを作成
2. その中にBASIC認証mod_rewriteを含めた.htaccessファイルを作成

### Basic Auth
AuthUserFile BASIC認証のパスワードファイル
AuthGroupFile /dev/null
AuthName "Input ID and Password."
AuthType Basic
require valid-user

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f

    # /members/にアクセスがあった場合は、/members/indexを呼び出す
    RewriteRule ^/$ ../index.php?url=members/index [QSA,L]

    RewriteRule ^(.*)$ ../index.php?url=members/$1 [QSA,L]
</IfModule>

解説
/members/xxxxにアクセスがあると、/members/.htaccessが適用され、BASIC認証が走ります。認証後、mod_rewriteで静的なファイル(/members/hoge.htmlとか)やディレクトリがなければ、一階層上のcakeのindex.phpを呼び出します。その際にパラメータにコントローラ名をセットしてあげて、該当のコントローラを呼び出します。/members/にアクセスがあった場合はアクション名が無く実ディレクトリが存在してindex.phpが呼ばれないので、indexアクションを呼ぶようにしてます。これを削ってindex.htmlとか置けば、そちらの静的ファイルが読み込まれます。


ここでは"members"というコントローラ名を個別に指定してるんだけど、動的にセットするとかできるんでしたっけ?知ってる方がいたら教えてください。やりたいのは、../index.php?url=%{REQUEST_DIRECTORY}/$1 みたいなことです。


結局、cakeへの渡し方(mod_rewrite)を何とかしてあげれば、何とでもなるということですね。

routes.phpで独自にmembersコントローラにアクセスできる別パスを持っている場合は、そっちにも同じような構成で作っておかないと抜けができるので注意!