9月に入りましたが、まだまだ暑い日が続きますね。アイスコーヒーとエアコンが欠かせません。さてここでbakerの皆さんに涼しくなる小話でも。
CakePHPでは1アクションがcontrollerの1メソッドになっています。アクション名(メソッド名)はリクエストのあったURLから決定されます。つまり外部からcontrollerのメソッドを実行できてしまうわけです。ただフレームワークがアクションメソッドだけをアクションとして実行するようにしてくれれば問題は無いはずです。ではURLで指定されたアクション(メソッド)がアクションメソッドかどうかどのように判断しているのでしょうか。
これが実は通常のメソッドとアクションメソッドとの区別は無いんですね。フレームワークはURLで指定されたアクション(メソッド)を単に呼んでいるだけなのです。つまりcontroller内のメソッドは外から呼び放題なわけです。
ちょっと涼しくなってきましたか?
こりゃいけないって事でアプリケーションのcontrollerではアクションメソッドだけを書きましょう、という話になるのですが、それだけではダメなんです。そう親クラスのControllerには多くのメソッドがあるんですね。それを継承しているんで、当然Controllerクラスのメソッドも呼び放題なわけです。
背中がゾクッとしてきましたね。
さらに付け加えるとURLの指定でメソッドに引数を与えることもできてしまいます。
怖いですねー。ホラーですねー。
で、どうしましょ。という話です。
まず以下に該当するメソッドはアクションとしては実行されません。
- メソッド名が[_](アンダースコア)ではじまるもの
- beforeFilter,beforeRender,afterFilterメソッド
- アクセス制御子がprivateのメソッド(PHP5のみ。これはPHP自身がFatal errorを出す)
これを見るとAppControllerや各controllerでは1.か3.のルールでメソッドを書けば大丈夫なようです。
ただControllerクラスのメソッドで上記のルールに該当しないものはやはり呼ばれてしまいます。とりあえずの実害は(おそらく)無いのでしょうけど、根本的に任意のメソッドを外部から呼ばれてしまうのは気持ち悪いです。そこでまたパッチ[cakephp_action_method.patch]を作りました。
このパッチではaction_~ではじまるメソッドのみをアクションとして実行します。アクションのメソッド名は[action_ + アクション名]になります。例えば/post/indexに対応するメソッド名は[action_index]になります。(ビューファイル名は従来とおりアクション名のみで良いです。)
[app/controllers/post_controller.php] < ?php class PostController extends AppController { function action_index() { // indexアクションとして呼ばれる } function other_method() { // これはアクションとして外部から呼ばれない } } ?>
これで外部からはcontrollerのaction_~以外のメソッドは呼べなくなります。精神衛生上はこの方が良いかと。無保証ですがよろしければどうぞ。
- Newer: Yahoo!スポーツ に注意
- Older: ヘッドフォンを2つ
持つ持ちたい
コメント (Close):6
- shun 06-09-12 (火) 13:01
-
ここは参考になりますか?(^.^)/~~~
http://manual.cakephp.org/chapter/security - shin 06-09-12 (火) 16:43
-
こんにちは。
いつもサイト参考にさせて頂いています。SecurityComponentなのですが、これは記事の内容には当てはまらないのではないでしょうか。
というのもSecurityComponentはアクション呼び出しに制限をかけるものであって、(アクション以外の)メソッド呼び出しを禁止するものでは無いように思います。requirePost()にしてもrequireAuth()にしても許可された方法さえ取ればメソッドは呼ばれてしまいますし。
どうでしょう。
- shun 06-09-14 (木) 11:09
-
なるほど。もともとcontrollerが持っているメソッドについての話なんですね。スミマセン。
cake/コントローラ名/flash/test_my_string/300
などとすると、任意の文字列が表示できてしまいますね。(さすがにサニタイズしてありますが……。)パッチも便利だと思います!ただ、cakephpプロジェクトがバージョンアップするたびに考え直さなければいけなくなりますね。開発者に制限を加えてしまう改良なので cakephpプロジェクトに取り込まれるかも分かりませんし……。
自分でも、もう少し研究してみます……。
requestAction からのリクエストと、ページからのajaxコール“だけ”を実行する方法は下記にもあるようです。
http://groups.google.com/group/cake-php/browse_thread/thread/eaa9a36f02475f4a/ - shun 06-09-14 (木) 11:44
-
cakephp ユーザがどう思っているのか、ML に投げてみました。(ついでに shin さんのページを紹介してしまいました。良かったでしょうか?)
http://groups.google.com/group/cake-php/browse_thread/thread/ed825eb48fedfbf2/ - shin 06-09-14 (木) 12:18
-
どもども。
パッチも便利だと思います!ただ、cakephpプロジェクトがバージョンアップするたびに考え直さなければいけなくなりますね。開発者に制限を加えてしまう改良なので cakephpプロジェクトに取り込まれるかも分かりませんし……。
そうなんですよねー。後々を考えるとパッチは避けたいところですね。
ちなみにComponentを使う方法としては以下があります。
http://cakeforge.org/snippet/detail.php?type=snippet&id=130ただこれはフレームワーク自体の問題だと思うので、できればフレームワーク側で対応したい(してほしい)、というのが私の考えです。
- shin 06-09-14 (木) 12:21
-
cakephp ユーザがどう思っているのか、ML に投げてみました。(ついでに shin さんのページを紹介してしまいました。良かったでしょうか?)
ありがとうございます。私も他のbakerがどう考えているのか気になるところなんで。
トラックバック:1
- このエントリーのトラックバックURL
- /blog/2006/09/cakephp_controller_action.html/trackback
- Listed below are links to weblogs that reference
- CakePHP Controller小話 from Shin x blog
- trackback from 眠るシーラカンスと新米プログラマー 07-04-06 (金) 2:09
-
cakePHP:…
cakePHPで部分的に動的なパーツを表示したい場合に、
別のコントローラのメソッドを利用するrequestActionという機能があります。それは良い (more…)