2016-10-23 5 views
2

Ich baue einen Webshop, der auf dem slim3 Framework basiert. Ich muss eine Server-zu-Server-POST-Anfrage bearbeiten, um zu bestätigen, ob die Zahlung erfolgreich war. Ich habe csrf in den Behälter wie folgt aus:Slim3 Route von CSRF Middleware ausschließen

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

und fügte hinzu, um es in die App wie folgt aus:

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

Und es funktioniert gut. Aber jetzt muss ich in der Lage sein, eine Ausnahme zu einer bestimmten Route hinzuzufügen, damit ich die Postanforderungen bekomme, die sie senden. Ich konnte bisher keine funktionierende Lösung finden.

Irgendwelche Ratschläge?

Antwort

2

Wenn Sie eine Route von einer Middleware ausschließen müssen, gibt es zwei Möglichkeiten:

Option 1: Gruppe Ihre Routen.

können Sie Gruppe alle Routen mit Ausnahme der:

<?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'); 

Option 2: Ihre eigene Middleware

Statt \Slim\Csrf\Guard mit direkt verwenden, nutzen Sie Ihre eigene Middleware, die es erweitert . Ihre Middleware überprüft die Route und wenn die Route "außergewöhnlich" ist, wird sie übersprungen.

dies Einstellungen hinzufügen, da Sie Route innerhalb Middleware zugreifen müssen:

<?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 
}; 

Jetzt einfach die Middleware \Slim\App Instanz hinzufügen:

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

die Middleware erstreckt orginial \Slim\Csrf\Guard erstellen

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

Nicht, wenn sich noch jemand die Haare auszieht (vor allem, wenn Sie Webhooks benutzen wollen).

Ich fand eine einfachere Lösung mit Hilfe von Georgys Antwort.

So stellen Sie die folgende Änderung an den tatsächlichen Schlank \ CSRF \ Guard Guard.php ' Datei und deren __invoke Methode. Oder einfach kopieren und den Code unten ein ...

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; 
}; 
Verwandte Themen