2016-10-23 5 views
2

私はslim3フレームワークに基づいてwebshopを構築しています。支払いが成功したかどうかを確認するために、サーバー間のPOSTリクエストを処理する必要があります。Slim3 CSRFミドルウェアからの経路を除外

$container['csrf'] = function($container) { 
    return new \Slim\Csrf\Guard; 
}; 

と、このようなアプリにこれを追加しました::

$app->add($container->csrf); 

そして、それは良い作品私はこのようなコンテナにCSRF追加しました。しかし、今私は特定のルートに例外を追加できるようにする必要がありますので、私は彼らが送信している投稿要求を取得します。 これまでのところ、実際の解決策を見つけることができませんでした。

アドバイスはありますか?

答えて

2

あなたはミドルウェアから1つのルートを除外するために必要がある場合は、2つのオプションがあります。

オプション1:グループあなたのルートは。

あなたはグループ1を除くすべてのルートすることができます

<?php 
$app->group('', function() { 

    // All routes declarations.... 

})->add($container->csrf); // Add middleware to all routes within the group 

// Declare your "exceptional" route outside the group 
$app->post('my-special-route-that-has-no-csrf-middleware', 'routeProcessor'); 

オプション2:代わりに、直接\Slim\Csrf\Guardを使用する独自のミドルウェア

を使用することは、それを拡張して、独自のミドルウェアを使用します。あなたのミドルウェアはルートをチェックし、ルートが "例外的な"ものであればスキップします。 orginial \Slim\Csrf\Guard拡張ミドルウェアを作成

$container['settings'] => [ 
    'determineRouteBeforeAppMiddleware' => true 
]; 

<?php 
class MyCsrfMiddleware extends Slim\Csrf\Guard 
{ 
    // This method is processing every request in your application 
    public function processRequest($request, $response, $next) { 
     // Check if it's your "exceptional" route 
     $route = $request->getAttribute('route'); 
     if ($route == 'my-special-path') { 
      // If it is - just pass request-response to the next callable in chain 
      return $next($request, $response); 
     } else { 
      // else apply __invoke method that you've inherited from \Slim\Csrf\Guard 
      return $this($request, $response, $next); 
     } 
    } 
} 

///////////// 

$container['csrf'] = function($container) { 
    return new MyCsrfMiddleware; // Now the container returns your middleware under 'csrf' key 
}; 

今単に\Slim\Appインスタンスにミドルウェアを追加します。 あなたがミドルウェア内のルートにアクセスする必要があるため

は、設定にこれを追加します

$app->add('csrf:processRequest'); 
1

まだ誰かがこれについて頭を引っ張っているわけではありません(特にウェブフックを使いたい場合)。

私はGeorgyの答えの助けを借りてより簡単な解決策を見つけました。

ただ、実際のスリム\ CSRF \ガード「Guard.php」ファイルとその__invokeメソッドに次の変更を行います。または、下にコードをコピーして貼り付けてください。

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) 
{ 

    $route = $request->getAttribute('routeInfo'); 

    $routeRequestInfo = $route['request']; 

    $requestUrl = $routeRequestInfo[1]; 


    if ($requestUrl == 'http://yoursite/the-url-you-want-to-exempt') 
    { 
     //This will just return the request to your application with applying the csrf. 
     return $next($request, $response); 

    } 
    else 
    { 

    $this->validateStorage(); 

    // Validate POST, PUT, DELETE, PATCH requests 
    if (in_array($request->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) { 
     $body = $request->getParsedBody(); 
     $body = $body ? (array)$body : []; 
     $name = isset($body[$this->prefix . '_name']) ? $body[$this->prefix . '_name'] : false; 
     $value = isset($body[$this->prefix . '_value']) ? $body[$this->prefix . '_value'] : false; 
     if (!$name || !$value || !$this->validateToken($name, $value)) { 
      // Need to regenerate a new token, as the validateToken removed the current one. 
      $request = $this->generateNewToken($request); 

      $failureCallable = $this->getFailureCallable(); 
      return $failureCallable($request, $response, $next); 
     } 
    } 

    // Generate new CSRF token if persistentTokenMode is false, or if a valid keyPair has not yet been stored 
    if (!$this->persistentTokenMode || !$this->loadLastKeyPair()) { 
     $request = $this->generateNewToken($request); 
    } 

    // Enforce the storage limit 
    $this->enforceStorageLimit(); 

    } 

    return $next($request, $response); 
} 
0
$container['csrf'] = function($container) { 
    $guard = new \Slim\Csrf\Guard; 
    $guard->setFailureCallable(function($request, $response, $next) use ($container) { 
     $request = $request->withAttribute("csrf_status", false); 
     if($request->getAttribute('csrf_status') === false) { 
      if($request->getAttribute('route')->getName()=== 'your-route-name'){ 
      return $next($request, $response); 
      } 
      return $response->withStatus(400)->withRedirect($container['router']->pathFor('home')); 
     } else { 
      return $next($request, $response); 
     } 
    }); 

    return $guard; 
}; 
関連する問題