2016-11-29 3 views
1

versagt Ich versuche, eine saubere Art und Weise zu finden, die AuthorizationException außer Kraft zu setzen eine dynamische Zeichenfolge zu nehmen, die zurückgeführt werden können, wenn eine Politik versagt.Laravel 5.3 Passing AuthorizationException eine Nachricht, wenn eine Politik

Dinge, die ich weiß ich tun kann, sind:

1) in der Steuerung die Politik Wrap mit einem Try-Catch, rethrow dann eine benutzerdefinierte Ausnahme, die eine bestimmte Zeichenfolge nimmt, die ausführliche scheint ein bisschen

2) abort(403, '...') in der Politik vor der Rückkehr, die da Politik ein bisschen hacky scheint bereits tun, um die Arbeit

und dann in/Ausnahmen/Handler :: render ich die Antwort als JSON zurückschicken können

gibt es ein netterer Weg dies zu tun, um eine Nachricht in der Antwort eines Richtlinienfehlers zu erhalten? oder ist 1 oder 2 meine beste Wahl.

+0

Sie möchten also einen benutzerdefinierten Fehler generieren, wenn eine AuthorizationException ausgelöst wird? – atefth

+0

Hallo @atefth yah wie wenn eine Validierung fehlschlägt und Sie erhalten die Fehler Tasche, aber in diesem Fall würden Sie einen fehlgeschlagenen Policy Bag mit einer Nachricht erhalten, die basierend auf der gescheiterten Richtlinie als JSON-Antwort variieren würde. – mtpultz

Antwort

1

Ich bemerkte, wenn Sie throw AuthorizationException($message) in einer Richtlinie mit Laravel-Ausnahme es springt Sie aus der Richtlinie, aber die Ausführung im Controller fortgesetzt wird, und nicht zu Handler::render fortschreitet. Was ich gehe davon aus das sie irgendwie die Ausnahmebehandlung, aber ich konnte nicht finden, wo sie es taten ... also wenn jemand findet, wo dies geschieht ich noch wissen möchten.

Wenn Sie erstellen Sie Ihre eigenen AuthorizationException und werfen es, wird es die Ausführung wie erwartet anhalten, und fallen in Handler::render so endete ich diese Methode, um meine Politik Aufsummierung:

use App\Exceptions\AuthorizationException; 

// ... removed for brevity 

private function throwExceptionIfNotPermitted(bool $hasPermission = false, bool $allowExceptions = false, $exceptionMessage = null): bool 
{ 
    // Only throw when a message is provided, or use the default 
    // behaviour provided by policies 
    if (!$hasPermission && $allowExceptions && !is_null($exceptionMessage)) { 

     throw new \App\Exceptions\AuthorizationException($exceptionMessage); 
    } 

    return $hasPermission; 
} 

Neue Ausnahme für nur in der Politik zu werfen in \App\Exceptions:

namespace App\Exceptions; 

use Exception; 

/** 
* The AuthorizationException class is used by policies where authorization has 
* failed, and a message is required to indicate the type of failure. 
* --- 
* NOTE: For consistency and clarity with the framework the exception was named 
* for the similarly named exception provided by Laravel that does not stop 
* execution when thrown in a policy due to internal handling of the 
* exception. 
*/ 
class AuthorizationException extends Exception 
{ 
    private $statusCode = 403; 

    public function __construct($message = null, \Exception $previous = null, $code = 0) 
    { 
     parent::__construct($message, $code, $previous); 
    } 

    public function getStatusCode() 
    { 
     return $this->statusCode; 
    } 
} 

die Ausnahme behandeln und die Nachricht in einer JSON-Antwort in Handler::render() bieten:

public function render($request, Exception $exception) 
{ 
    if ($exception instanceof AuthorizationException && $request->expectsJson()) { 

     return response()->json([ 
      'message' => $exception->getMessage() 
     ], $exception->getStatusCode()); 
    } 

    return parent::render($request, $exception); 
} 

und ich habe es auch von der Anmeldung Handler::report entfernt.

-1

Laravel hat eine Option, Argumente zu übergeben, die Fehler in der authorize() Methode einer Controller Klasse anpassen zugegriffen durch die Gate der Klasse Umsetzung der GateContract zur Verfügung gestellt von der Gate Fassade.

Allerdings scheint es, dass sie diese Argumente zu den allow()/deny() Methoden verantwortlich für die Rückgabe Fehlermeldungen, implementiert in der HandlesAuthorization Trait passieren vergessen.


Sie müssen diese Argumente zu übergeben, indem Sie folgende Schritte ausführen:

  1. Ändern Sie die authorize Methode in der vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php Datei

    public function authorize($ability, $arguments = []) { 
        $result = $this->raw($ability, $arguments); 
        if ($result instanceof Response) { 
         return $result; 
        } 
    
        return $result ? $this->allow() : $this->deny($arguments); 
    } 
    
  2. Anruf authorize von der Steuerung mit einem zusätzlichen Argument, das heißt: Ihre benutzerdefinierten $message -

    $message = "You can not delete this comment!"; 
    $response = $this->authorize('delete', $message); 
    

ich pull request gemacht haben, dies zu beheben, wird hoffentlich jemand es bald fusionieren.

+0

Schön, wir verwenden die Modellrichtlinie '$ user-> can (...);' also werde ich nach dieser Art von Lösung suchen und sehen, ob es funktioniert. Sieht auch so aus, als ob deine PR auf temporären/permanenten Halt gesetzt wurde :( – mtpultz