2013-11-28 2 views
15

슬림에서는 미들웨어 내에서 현재 경로를 얻을 수 있습니까?미들웨어에서 슬림 한 PHP 루트

class Auth extends \Slim\Middleware{ 
    public function call(){ 
    $currentRoute = $this->app->getRoute(); // Something like this? 
    } 
} 

은 내가 slim.before.dispatch 후크가 호출 후 $app->router()->getCurrentRoute()를 호출 할 수 있습니다 알고 있지만, 당신은 미들웨어에서이 호출 할 때이 아닌 개체를 반환합니다. 어떤 도움이라도 대단히 감사하겠습니다.

답변

19

예 아니요. Slim의 소스 코드를 보면 Slim::run 메서드가 호출 될 때 등록 된 미들웨어가 LIFO 순서로 호출 된 것을 볼 수 있으며 Slim은 요청 처리가 시작되는 자체 "호출"메서드를 실행합니다. Slim이 경로를 구문 분석하고 처리하는 것은이 방법에 있습니다. 이 경우 Middleware::call 메서드에서 $app->router()->getCurrentRoute() 메서드에 액세스 할 수 없습니다.이 메서드는 아직 구문 분석 및 정의되지 않았기 때문에 사용할 수 없습니다.

미들웨어 내부의 slim.before.dispatch에 리스너를 등록하고 해당 방법으로 수행하려는 작업을 구현하는 유일한 방법입니다.

클래스 이름에서 기본 인증 모듈을 만들려고한다고 가정합니다. 나는 전에이 비슷한 짓을했는지, 그리고이 같은 갔다 다음 onBeforeDispatch 방법은 핸들러가 호출 경로의 전에 실행됩니다,이 예제에서는

class AuthMiddleware extends \Slim\Middleware 
{ 
    public function call() 
    { 
     $this->app->hook('slim.before.dispatch', array($this, 'onBeforeDispatch')); 

     $this->next->call(); 
    } 

    public function onBeforeDispatch() 
    { 
     $route = $this->app->router()->getCurrentRoute(); 

     //Here I check if the route is "protected" some how, and if it is, check the 
     //user has permission, if not, throw either 404 or redirect. 

     if (is_route_protected() && !user_has_permission()) 
     { 
      $this->app->redirect('/login?return=' . urlencode(filter_input(INPUT_SERVER, 'REQUEST_URI'))); 
     } 
    } 
} 

합니다. 소스 코드를 살펴보면 $app->redirect()$app->pass() 등의 예외를 수신하는 try/catch 블록 내부에서 이벤트가 발생하는 것을 볼 수 있습니다. 즉, 여기에 체크/리디렉션 로직을 구현할 수 있음을 의미합니다. 경로 처리기 기능.

위의 is_route_protecteduser_has_permission은 인증 미들웨어의 작동 방식을 나타내는 의사 코드입니다. 클래스를 구조화하여 미들웨어 생성자의 경로에 대한 경로 또는 정규 표현식의 목록을 지정하고 사용자 권한 검사 등을 구현 한 서비스 객체를 전달할 수 있도록했습니다. 이것이 도움이되기를 바랍니다.

+0

좋은 것. 깔끔한 솔루션과 상세한 설명에 감사드립니다. 미들웨어의 call() 함수에 후크를 등록하는 것이 좋은 지점입니까? 그것은 그것이 깔끔하게 보관되어 있기 때문에 훅이 등록/호출되는 원인이 될 수 있는지 궁금합니다. – plong0

+3

나는 호출 메서드가 요청 당 한 번만 호출된다고 가정하는 것이 안전하다고 생각합니다. 실제로는 체인에서 이전 미들웨어를 구현하는 데 의존합니다. 디자인에서 각 미들웨어가 다음에 호출하는 단일 링크 목록을 사용하기 때문입니다. 미들웨어가 Chain에서 메소드를 두 번 호출하면 Doing It Wrong ™을 제안하지만 아마 사용을 중단해야합니다. :) –

+0

감사합니다. 작동 중입니다. – mapodev

2

app-> getRoute() 대신 app-> request() -> getPathInfo()를 사용해야합니다.

class Auth extends \Slim\Middleware{ 
    public function call(){ 
     $currentRoute = $this->app->request()->getPathInfo(); 
    } 
} 
3

동일한 상황에 처한 다른 방법이 있습니다. 내가 경로를 통한 아무것도 일치했다 피하기 위해 원하고 당신이 시도 할 수 있도록 다음, 대신 경로 이름을 사용하고 싶었 : 심지어 경로의 배열을 가질 수

public function call() { 

    $routeIWantToCheckAgainst = $this->slimApp->router()->urlFor('my.route.name'); 
    $requestRoute = $this->slimApp->request()->getPathInfo(); 
    if ($routeIWantToCheckAgainst !== $requestRoute) { 
     // Do stuff you need to in here 
    } 

    $this->next->call(); 
} 

당신이 미들웨어가 실행하지 않으 그런 다음 in_array() 등이 맞는지 확인하고 그렇지 않은 경우 필요한 것을 수행하십시오.