2017-01-09 4 views
0

Ich habe vor einiger Zeit eine App mit Slim 2 erstellt und ich versuche, Angular hinzuzufügen. Es läuft bisher gut, aber ich kann den CSRF-Schutz, den ich verwendet habe, nicht mehr verwenden, da Angular alle meine Post-Anfragen bearbeitet. Unten ist die Before Middleware, die ich gearbeitet habe.Angular XSRF zur Slim-App hinzufügen - Ist das der Sound?

<?php 

namespace Cache\Middleware; 

use Exception; 
use Slim\Middleware; 

class CsrfMiddleware extends Middleware { 
protected $key; 

public function call() { 

    $this->key = $this->app->config->get('csrf.key'); 

    $this->app->hook('slim.before', [$this, 'check']); 

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

public function check() { 
    if (!isset($_SESSION[$this->key])) { 
     $_SESSION[$this->key] = $this->app->hash->hash($this->app->randomlib->generateString(128)); 
    } 

    $token = $_SESSION[$this->key]; 

    if (in_array($this->app->request()->getMethod(), ['POST', 'PUT', 'DELETE'])) { 
     $submittedToken = $this->app->request()->post($this->key) ?: ''; 

     if (!$this->app->hash->hashCheck($token, $submittedToken)) { 
      throw new Exception('CSRF token mismatch'); 
     } 
    } 

    $this->app->view()->appendData([ 
     'csrf_key' => $this->key, 
     'csrf_token' => $token 
    ]); 
} 

}

Ich weiß, dass Winkel automatisch für einen Token sieht namens XSRF-TOKEN und fügt sie den Header als X-XSRF-token. Wie kann ich die Middleware ändern, um die richtigen Werte zu schreiben, zu lesen und zu vergleichen?

EDIT:

Nach erneuten Blick auf diese und die schlanke Dokumentation überprüft, ich die Zeile geändert:

$submittedToken = $this->app->request()->post($this->key) ?: ''; 

dazu:

$submittedToken = $this->app->request->headers->get('X-XSRF-TOKEN') ?: ''; 

Wenn ich mich nicht irre , dies weist $ submittedToken den übergebenen Wert als X-XSRF-TOKEN im Header zu. Es wirft die Ausnahme mit der Nachricht von der Middleware "CSRF token mismatch". Das fühlt sich an wie Fortschritt. Im Folgenden finden Sie die entsprechende Winkel:

app.controller('itemsCtrl', ['$scope', '$http', function($scope, $http) { 

    // Initailize object when the page first loads 
    $scope.getAll = function() { 
     $http.post('/domain.com/admin/getNames').success(function(data) { 
      $scope.names = data; 
     }); 
    } 

EDIT

unten ist, wo jetzt der PHP-Code steht. Ich denke, das funktioniert. Ich habe den erwarteten CSRF-Fehler erhalten, wenn ich den Cookie lösche oder den Wert des $ -Tokens ändere, bevor ich ein Formular abschicke. Ich bin ein wenig besorgt darüber, was passieren wird, wenn ich mehrere Benutzer habe. Ich habe es noch nicht getestet. Beruht der Schutz auf der Grundlage dieser Revision?

<?php 

namespace Cache\Middleware; 

use Exception; 
use Slim\Middleware; 

class CsrfMiddleware extends Middleware { 
protected $key; 

public function call() { 

    $this->key = $this->app->config->get('csrf.key'); 

    $this->app->hook('slim.before', [$this, 'check']); 

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

public function check() { 
    // if (!isset($_SESSION[$this->key])) { 
    if (!isset($_SESSION[$this->key])) { 
     // $_SESSION[$this->key] = $this->app->hash->hash($this->app->randomlib->generateString(128)); 
     $this->app->setcookie($this->key, $this->app->hash->hash($this->app->randomlib->generateString(128))); 
    } 

    // $token = $_SESSION[$this->key]; 
    if(isset($_COOKIE[$this->key])) { 
     $token = $_COOKIE[$this->key]; 
    } 

    if (in_array($this->app->request()->getMethod(), ['POST', 'PUT', 'DELETE'])) { 
     // $submittedToken = $this->app->request()->post($this->key) ?: ''; 
     $submittedToken = $this->app->request->headers->get('X-XSRF-TOKEN') ?: ''; 

     if (!$this->app->hash->hashCheck($token, $submittedToken)) { 
      throw new Exception('CSRF token mismatch'); 
     } 
    } 
} 
} 

Antwort

0

Vom Angular docs for $http Cross Site Request Forgery (XSRF) Protection:

Der Name der Header angegeben werden, können die xsrfHeaderName und xsrfCookieName Eigenschaften entweder $ httpProvider.defaults bei config-Zeit verwenden, $ http.defaults zur Laufzeit, oder das pro-Anfrage-Konfigurationsobjekt.

Ändern Sie diese Werte, um sie so zu ändern, dass sie einen anderen Cookie-Namen/Kopfzeilennamen verwenden.

+0

Ich habe gesehen, dass anderswo implementiert. Im Moment habe ich den csrf.key-Namen in XSRF-TOKEN geändert, sodass er von Angular aufgenommen wird. Nicht sicher, wie man testet, wenn das funktioniert. Auch nicht sicher, wie man die Middleware zum Lesen des Header-Namens bekommt? – user2530671

Verwandte Themen