MVCでの自動トークンチェックの例。
フォームにトークンを追加します。
--- a/app/views/signup/index.phtml
+++ b/app/views/signup/index.phtml
@@ -4,6 +4,10 @@
<?php echo Tag::form("signup/register"); ?>
+<!-- CSRF対策のトークン -->
+<input type="hidden" name="<?php echo $this->security->getTokenKey() ?>"
+ value="<?php echo $this->security->getToken() ?>"/>
+
<p>
<label for="name">Name</label>
<?php echo Tag::textField("name") ?>
そして、
--- a/public/index.php
+++ b/public/index.php
@@ -11,6 +11,47 @@ try {
//Create a DI
$di = new Phalcon\DI\FactoryDefault();
+ // CSRF対策にセッションを使うので自動でスタートするように
+ $di->setShared('session', function() {
+ $session = new \Phalcon\Session\Adapter\Files();
+ $session->start();
+ return $session;
+ });
+
+ // CSRF対策をディスパッチャーで実装
+ $di->set('dispatcher', function() use ($di) {
+ $eventsManager = new Phalcon\Events\Manager();
+ // beforeDispatchLoopにイベントを設定
+ $eventsManager->attach(
+ "dispatch:beforeDispatchLoop",
+ function($event, $dispatcher) use ($di) {
+ // POSTメソッドのみを対象に
+ if ($di->get('request')->getMethod() !== 'POST') {
+ return;
+ }
+ // トークンをチェックして例外を投げる
+ if (! $di->get('security')->checkToken()) {
+ throw new \Exception('Token error!');
+ }
+ }
+ );
+ // 例外を受けるためにbeforeExceptionにイベントを設定
+ $eventsManager->attach(
+ "dispatch:beforeException",
+ function($event, $dispatcher, $exception) {
+ // トークンエラーの例外の場合、そのままその例外を投げる
+ if ($exception->getMessage() === 'Token error!') {
+ throw $exception;
+ }
+ }
+ );
+
+ $dispatcher = new Phalcon\Mvc\Dispatcher();
+ $dispatcher->setEventsManager($eventsManager);
+
+ return $dispatcher;
+ });
+
//Setup the database service
$di->set('db', function(){
return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
@@ -38,6 +79,7 @@ try {
//Handle the request
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();
-} catch(\Phalcon\Exception $e) {
- echo "PhalconException: ", $e->getMessage();
+} catch(\Exception $e) {
+ // 最終的にすべての例外をここでキャッチ
+ echo "Exception: ", $e->getMessage();
}
http://blog.a-way-out.net/blog/2014/12/16/phalcon-tutorial-csrf/ より