2016-05-25 17 views
1

私はSymfonyですべての経路で必要とする「標準手順」を持っています。 私は基本的に短い(相対的に)一意の番号を作成し、アクセス許可を確認し、その関数が呼び出されたことを記録します。Symfonyの@Routeコールの手順をEventListenerで簡略化

** 
* @Route("/_ajax/_saveNewClient", name="saveNewClient") 
*/ 
public function saveNewClientAction(Request $request) 
{ 

    /* Create Unique TrackNumber */ 
    $unique= $this->get('log')->createUnique(); 

    /* Check Permission */ 
    if (!$permission = $this->get('permission')->needsLevel(2, $unique)) { 

     /* Log Action */ 
     $this->get('log')->writeLog('No Permission, 2 needed', __LINE__, 4); 
     return new JsonResponse(array(
       'result' => 'error', 
       'message' => 'Insufficient Permission' 
      ) 
     ); 
    } 

    /* Log Action */ 
    $this->get('log')->writeLog('called '.__FUNCTION__, __LINE__, 1, $unique); 

    return $this->render(':admin:index.html.twig', array()); 

} 

どこか1つの関数にすべてのことを配置する方法はあります:ここで

は一例ですか?

writeLogも同様に関数の他の部分で呼び出されるため、もちろんこれは可能ですが、許可チェックと組み合わせることは望ましくありません。

EventListenerを作成する際には、すべての関数でそれを呼び出す必要がありますか、それとも自動的に呼び出すことはできますか?

何かヒントありがとうございます!

答えて

0

beforefilterを作成しようとする可能性があります。それはちょうど前に、またはちょうどあなたのコントローラのアクションは、フィルタとして機能した後に実行されるように、いくつかのロジックを必要とするWebアプリケーション開発では非常に一般的ですどのように前に設定し、後にフィルター

http://symfony.com/doc/current/cookbook/event_dispatcher/before_after_filters.html

かフック。

一部のWebフレームワークでは、preExecute()やpostExecute()などのメソッドを定義していますが、Symfonyにはそのようなものはありません。良いニュースは、EventDispatcherコンポーネントを使用するRequest-> Responseプロセスを妨害するより良い方法があるということです。

トークンの検証例

あなたには、いくつかのコントローラは、公開されているが、いくつかの他のものは、1つまたはいくつかのクライアントに制限されているAPIを開発する必要があることを想像してみてください。これらのプライベート機能のために、あなた自身を識別するためにクライアントにトークンを提供するかもしれません。

コントローラのアクションを実行する前に、アクションが制限されているかどうかを確認する必要があります。制限されている場合は、提供されたトークンを検証する必要があります。

このレシピでは、トークンがconfigで定義され、データベースの設定もセキュリティコンポーネントによる認証も使用されないことに注意してください。

YAML

# app/config/config.yml 
parameters: 
    tokens: 
     client1: pass1 
     client2: pass2 

タグコントローラへ:kernel.controllerイベントとフィルタの前に

まず、キーconfig.ymlとパラメータを使用して、いくつかの基本的なトークンの設定を保存チェックしてください

rnel.controllerリスナーは、コントローラが実行される直前に、すべての要求に対して通知を受け取ります。したがって、まず、要求に一致するコントローラがトークンの検証を必要としているかどうかを特定する方法が必要です。作成

namespace AppBundle\Controller; 

use AppBundle\Controller\TokenAuthenticatedController; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class FooController extends Controller implements TokenAuthenticatedController 
{ 
    // An action that needs authentication 
    public function barAction() 
    { 
     // ... 
    } 
} 

namespace AppBundle\Controller; 

interface TokenAuthenticatedController 
{ 
    // ... 
} 

単純にこのインタフェースを実装するコントローラは次のようになります。

清潔で簡単な方法は、コントローラがそれを実装する空のインターフェイスを作成し、作ることですイベントリスナー

次に、必要なロジックを保持するイベントリスナーを作成する必要がありますあなたのコントローラの前に実行されます。あなたがイベントリスナーに慣れていない場合は、イベント・リスナーとユーザを作成するための方法でそれらについての詳細を学ぶことができます。

// src/AppBundle/EventListener/TokenListener.php 
namespace AppBundle\EventListener; 

use AppBundle\Controller\TokenAuthenticatedController; 
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; 
use Symfony\Component\HttpKernel\Event\FilterControllerEvent; 

class TokenListener 
{ 
    private $tokens; 

    public function __construct($tokens) 
    { 
     $this->tokens = $tokens; 
    } 

    public function onKernelController(FilterControllerEvent $event) 
    { 
     $controller = $event->getController(); 

     /* 
     * $controller passed can be either a class or a Closure. 
     * This is not usual in Symfony but it may happen. 
     * If it is a class, it comes in array format 
     */ 
     if (!is_array($controller)) { 
      return; 
     } 

     if ($controller[0] instanceof TokenAuthenticatedController) { 
      $token = $event->getRequest()->query->get('token'); 
      if (!in_array($token, $this->tokens)) { 
       throw new AccessDeniedHttpException('This action needs a valid token!'); 
      } 
     } 
    } 
} 

最後に、サービスとしてあなたのリスナーを登録し、リスナー

を登録し、それをイベントリスナーとしてタグ付けします。 kernel.controllerをリッスンすることで、コントローラが実行される直前にリスナーが呼び出されるようにSymfonyに指示します。この構成により

YAML

# app/config/services.yml 
services: 
    app.tokens.action_listener: 
     class: AppBundle\EventListener\TokenListener 
     arguments: ['%tokens%'] 
     tags: 
      - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } 

、あなたのTokenListener onKernelController方法は、それぞれの要求に応じて実行されます。実行しようとしているコントローラがTokenAuthenticatedControllerを実装している場合、トークン認証が適用されます。これにより、任意のコントローラー上に "前"フィルターがあります。

+0

これは非常に有望ですが、実際にはわかりませんが。しかし、私はそれが働くようになると思う... – PrimuS

+0

okeyは私の仕事を教えてください。 –