Laravel Passport’s Password Grant Flow für Erstanbieter-Apps

Lesezeit: 6 Minuten

Benutzer-Avatar
Markus

Ich benutze Laravel-Pass um Drittanbieter-Apps Zugriff auf einige Teile meiner API zu gewähren.

Aber ich verwende auch meine eigene API über meine eigene Erstanbieter-Native-Android-App. Also habe ich das ganze Internet nach der besten Praxis in diesem Fall durchsucht, bin aber hängengeblieben, um zu einem Schluss zu kommen.

Hier sind die Möglichkeiten, die ich gefunden habe:

Möglichkeit #01

Ich kann dem folgen Flow für die Gewährung des Passworts für Benutzeranmeldeinformationen.
In diesem Fall muss ich a bestehen client_secret und client_id zum Autorisierungsserver. Um sie sicher zu halten, kann ich sie nicht in den Quellcode meiner mobilen Anwendung schreiben (APKs sind dekompilierbar …).

Also, ich habe 2 Möglichkeiten.

Möglichkeit Nr. 01 – Wahl A

Proxy über meinen eigenen Server und Einfügen des Geheimnisses vor dem Aufrufen des oauth-Endpunkts:

$proxy = Request::create('/oauth/token', 'post', [
    'grant_type' => 'password',
    'client_id' => 1,
    'client_secret' => 'myownclientsecretishere',
    'username' => $username,
    'password' => $password
]);
$proxy->headers->set('Accept', 'application/json');
$response = app()->handle($proxy);

Möglichkeit Nr. 01 – Wahl B

Fügen Sie das Geheimnis ein, wenn Sie den oauth-Endpunkt mit einer Middleware aufrufen:

class InjectPasswordGrantSecret
{
    public function handle($request, Closure $next)
    {
        $request->request->add([
            'client_id' => 1,
            'client_secret' => 'myownclientsecretishere'
        ]);
        return $next($request);
    }
}

Dies sind Arbeitsbeispiele, aber sie sind auch ressourcenhungrig. Ich habe versucht, sie zu verwenden Apache-Benchmark auf meinem lokalen Rechner und ich habe ungefähr 9 Anfragen/Sekunde bekommen.

Möglichkeit #02

Ich kann dem folgen Gewährung des persönlichen Zugangs.
Dieser hier sieht nicht wie ein Standard aus OAuth2ermöglicht es uns, ein Token über eine beliebige benutzerdefinierte Route zu erstellen, einfach so:

if (! auth()->attempt(compact('username', 'password'))) {
    return error_response(__('auth.failed'));
}
$user = auth()->user();
$token = $user->createToken(null)->accessToken;

Verwenden Apache-Benchmark Ich bekomme ein besseres Ergebnis (etwa 30 Anfragen/Sekunde).

Die Lebensdauer des Tokens ist jedoch standardmäßig nicht konfigurierbar und auf 1 Jahr festgelegt (beachten Sie, dass es Problemumgehungen gibt, um diese Lebensdauer mithilfe eines benutzerdefinierten Anbieters konfigurierbar zu machen).

Ich frage mich wirklich, ob diese Lösung in einer Produktionsumgebung verwendet werden soll.

Anfangs habe ich verwendet JWT Tymon Bibliothek, weil ich nur meine eigene App hatte. Aber jetzt, da ich es mit Erstanbieter- UND Drittanbieter-Apps zum Laufen bringen muss, dachte ich, dass OAuth2 (über Laravel Passport) eine gute Lösung wäre …

Ich hoffe, jemand kann mir dabei helfen und erklären, was eine gute Lösung sein könnte, damit es sicher funktioniert und funktioniert [not slowly] auf Produktionsservern.

  • Hast du es versucht laravel.com/docs/5.7/passport#token-lifetimes? Ich denke, es gilt für persönliche und Passwort-Grant-Token.

    – Ali Farhoudi

    30. Oktober 2018 um 6:29 Uhr

  • Sieh dir das an: github.com/laravel/passport/issues/162#issuecomment-319157793

    – Ali Farhoudi

    30. Oktober 2018 um 6:31 Uhr

  • @AliFarhoudi Wie ich schon sagte (Ihr Link bestätigt dies). Die Lebensdauer der persönlichen Zugriffsgewährung kann mithilfe eines benutzerdefinierten Anbieters konfiguriert werden (Umgehung). Aus diesem Grund bin ich mir nicht sicher, ob ich dies für meine eigene Android-App in der Produktion verwenden sollte.

    – Markus

    30. Oktober 2018 um 9:04 Uhr

  • Bei einem benutzerdefinierten Anbieter müssen Sie sich keine Sorgen machen. Wenn das Framework dies nicht berücksichtigt hat, können Sie dies auf Ihre benutzerdefinierte Weise implementieren.

    – Ali Farhoudi

    30. Oktober 2018 um 15:02 Uhr

  • @Marc In diesem Fall würde ich sagen, wenn möglich, auf 6 aktualisieren, damit Sie es einfach verwenden können Passport::personalAccessTokensExpireIn in AuthServiceProvider.

    – Wouter Florijn

    6. November 2020 um 11:36 Uhr

Benutzer-Avatar
Onur Demir

Hier ist die Seite, auf die ich immer verweise: https://oauth2.thephpleague.com/authorization-server/which-grant/
Geben Sie hier die Bildbeschreibung ein

Es sagt

Wir empfehlen aus mehreren Gründen dringend, dass Sie den Autorisierungscodefluss über die Passwortgewährung verwenden. Wir eliminieren die Passworterteilungsoption.

Dann steht im Diagramm deutlich, dass Sie verwenden sollten

Authorization Code Grant mit PKCE

und weist auch darauf hin

Wenn der Client eine Webanwendung ist, die vollständig auf dem Front-End ausgeführt wird (z. B. eine Einzelseiten-Webanwendung) oder eine native Anwendung wie eine mobile App, sollten Sie die Autorisierungscodegewährung mit der PKCE-Erweiterung implementieren. Im Dokument können Sie weiterlesen.

Zusätzlich gibt es hier ein gutes Tutorial, das jedes Detail des Ablaufs anhand eines Beispiels erklärt:
https://auth0.com/docs/architecture-scenarios/mobile-api

Ich hoffe, diese helfen.

PS: Als ich meine Benutzer in meiner Erstanbieteranwendung autorisieren musste, hatte ich die Kennworterteilung verwendet, indem ich auf genau dieses Diagramm verwiesen hatte. Es scheint sich jedoch geändert zu haben, und die Kennworterteilung ist jetzt keine bewährte Methode mehr und wird nicht empfohlen.

Was ich zuvor getan habe, ist, meinen eigenen Controller zu implementieren, der die erweitert Laravel\Passport\Http\Controllers\AccessTokenController. Sie können diesen Controller nicht nur so einrichten, dass er die Erstellung der Token übernimmt, Sie können auch Routen zum Aktualisieren und Widerrufen der Token hinzufügen.

Ich hatte zum Beispiel eine create Methode zum Anzeigen des Anmeldeformulars, a store Verfahren zum Erstellen des Zugriffstokens, a refresh Verfahren zum Verwenden des Aktualisierungstokens zum Aktualisieren abgelaufener Zugriffstoken, und a revoke Methode zum Widerrufen des bereitgestellten Zugriffstokens und des zugehörigen Aktualisierungstokens.

Ich kann keinen genauen Code bereitstellen, da das Projekt nicht Open Source ist, aber dies ist ein kurzer Beispielcontroller mit nur dem store Methode:

use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Laravel\Passport\Http\Controllers\AccessTokenController;

class MyAccessTokenController extends AccessTokenController
{
    public function store(Request $request, ServerRequestInterface $tokenRequest)
    {
        // update the request to force your grant type, id, secret, and scopes
        $request->request->add([
            'grant_type' => 'password',
            'client_id' => 'your-client-id',
            'client_secret' => 'your-client-secret',
            'scope' => 'your-desired-scopes',
        ]);

        // generate the token
        $token = $this->issueToken($tokenRequest->withParsedBody($request->request->all()));

        // make sure it was successful
        if ($token->status() != 200) {
            // handle error
        }

        // return the token
        return $token;
    }
}

Das refresh Methode wäre im Grunde die gleiche, aber die grant_type wäre refresh_token.

Das revoke -Methode würde das Token des authentifizierten Benutzers abrufen ($token = $request->user()->token()widerrufe es ($token->revoke()) und gehen Sie dann manuell durch die oauth_refresh_tokens Tabelle für die zugehörigen Token (access_token_id = $token->id) und aktualisieren Sie die revoked Feld zu true.

Erstellen Sie einige Routen, um Ihren benutzerdefinierten Controller zu verwenden, und Sie können loslegen (NB: die revoke Route benötigt die auth:api Middleware).

  • Also, wenn ich es verstehe, fügen Sie in Ihrer Lösung Ihrer Anfrage Daten hinzu (Secrets, Grant_type..), um Token auszugeben (mit der IssueToken-Methode, die von AccessTokenController kommt), und vermeiden dann eine zusätzliche HTTP-Anfrage? [compared to my solution 1a]

    – Markus

    8. November 2018 um 8:33 Uhr

  • Können Sie erklären, was dies besser macht, als einfach Personal Access Grant oder eine andere Lösung zu verwenden?

    – Markus

    8. November 2018 um 8:35 Uhr


1141100cookie-checkLaravel Passport’s Password Grant Flow für Erstanbieter-Apps

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy