Skip to content

Instantly share code, notes, and snippets.

@okapon
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okapon/88f5bd56a886c287a7d1 to your computer and use it in GitHub Desktop.
Save okapon/88f5bd56a886c287a7d1 to your computer and use it in GitHub Desktop.
昔作ったオレオレ認証 AuthListener SlideShare ( http://www.slideshare.net/okapon/symfony10 )の補足資料
<?php
namespace My\BlogBundle\EventListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use My\BlogBundle\Exception\AuthException;
class AuthListener
{
// コンストラクターは省略してます
public function onKernelController(FilterControllerEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
$c = $event->getController();
if (!is_array($c)) {
return;
}
$controller = $c[0];
// 要認証ページでなければ何もしない
if (!method_exists($controller, 'isSecure') || !$controller->isSecure()) {
return;
}
// 認証除外に指定しているAccionはパスする
$route = $event->getRequest()->attributes->get('_route');
if (method_exists($controller, 'getIgnoreRoutes') && in_array($route, $controller->getIgnoreRoutes())) {
return;
}
// 要認証ページで、さらに未認証状態なら例外を投げる
if (!$this->auth->getUser()) {
$this->session->set('auth_referrer', $event->getRequest()->getUri());
throw new AuthException;
}
}
}
<?php
namespace My\BlogBundle\EventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use My\BlogBundle\Exception\AuthException;
class AuthExceptionListener
{
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
if ($exception instanceof AuthException) {
$event->setResponse(new RedirectResponse('/login', 302));
}
}
}
@okapon
Copy link
Author

okapon commented Jul 25, 2014

Listener登録
※ コンストラクター等は省略してます

services:
    my.blog.auth_listener:
        class: My\BlogBundle\EventListener\AuthListener
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
    my.blog.auth_exception_listener:
        class: My\BlogBundle\EventListener\AuthExceptionListener
        tags:
            - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

コントローラー

<?php

namespace My\BlogBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;

**
 * @Route("/blog")
 * @Template()
 */
class BlogController extends Controller
{
    public function isSecure()
    {
        // ログイン必須のコントローラーにする
        return true;
    }

    /**
     * @Route("/", name="blog_index")
     */
    public function indexAction()
    {
        // 略
    }
}

isSecureはマーカーとしての役割しか担っていないのでSymfony的にはannotationを使うのが良いとは思います。

@okapon
Copy link
Author

okapon commented Jul 25, 2014

余談ですが、FilterControllerEventは実行されるコントローラー自体置き換えることが可能です。
状況に応じて実行されるコントローラーを自体を差し替えることもできます。

    public function onKernelController(FilterControllerEvent $event)
    {
        // ex. https://example.com/user にアクセス
        // 初回登録時だけコントローラーを変える
        if ($this->doseNeedFirstRegister($event->getRequest())) {
            $userController = new FirstUserController();
            $userController->setContainer($this->container);
            $event->setController([$userController, 'registerAction']);
        }
    }

大体のケースではリダイレクトで事足りるとは思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment