web-dev-qa-db-fra.com

Personnalisation de la réponse du jeton Laravel Passport

Je travaille actuellement sur une API et j'ai heurté un mur de briques. J'utilise Passport avec le type de subvention "Mot de passe".

Je souhaite renvoyer les informations utilisateur avec les jetons d'accès, mais je ne sais pas comment.

Quelle classe pourrais-je implémenter, modifier ou étendre pour obtenir cela?.

J'aimerais que cela soit retourné:

{
    "token_type": "Bearer",
    "expires_in": 31536000,
    "access_token": "lalalalalal",
    "refresh_token": "lalalallala",
    "user": {
        "username": "a username",
        "user_type": "admin"
    }
}

Merci d'avance.

17
Irvin Chan

Les instructions sur la façon de procéder sont indiquées dans la classe BearerTokenResponse (qui fait partie du package league/oauth2-server).

Testé sur Laravel 5.7.

1. Étendez la classe BearerTokenResponse, ajoutez les paramètres supplémentaires dont vous avez besoin dans la réponse .

namespace App\Auth;

use League\OAuth2\Server\Entities\AccessTokenEntityInterface;

class BearerTokenResponse extends \League\OAuth2\Server\ResponseTypes\BearerTokenResponse
{
    /**
     * Add custom fields to your Bearer Token response here, then override
     * AuthorizationServer::getResponseType() to pull in your version of
     * this class rather than the default.
     *
     * @param AccessTokenEntityInterface $accessToken
     *
     * @return array
     */
    protected function getExtraParams(AccessTokenEntityInterface $accessToken): array
    {
        return [
            'user_id' => $this->accessToken->getUserIdentifier(),
        ];
    }
}

2. Créez votre propre classe PassportServiceProvider et remplacez la méthode makeAuthorizationServer() afin de passer dans votre propre classe BearerTokenResponse.

namespace App\Providers;

use App\Auth\BearerTokenResponse;
use Laravel\Passport\Bridge;
use League\OAuth2\Server\AuthorizationServer;

class PassportServiceProvider extends \Laravel\Passport\PassportServiceProvider
{
    /**
     * Make the authorization service instance.
     *
     * @return \League\OAuth2\Server\AuthorizationServer
     */
    public function makeAuthorizationServer()
    {
        return new AuthorizationServer(
            $this->app->make(Bridge\ClientRepository::class),
            $this->app->make(Bridge\AccessTokenRepository::class),
            $this->app->make(Bridge\ScopeRepository::class),
            $this->makeCryptKey('private'),
            app('encrypter')->getKey(),
            new BearerTokenResponse() // <-- The class you created above
        );
    }
}

3. Ajoutez votre fournisseur au tableau des fournisseurs dans config/app.php

    /*
     * Application Service Providers...
     */
    App\Providers\PassportServiceProvider::class,

4. Exclure le paquet de passeport de laravel découverte automatique dans composer.json

Cela empêche le chargement de la classe PassportServiceProvider par défaut.

    "extra": {
        "laravel": {
            "dont-discover": [
                "laravel/passport"
            ]
        }
    },

Exécutez ensuite composer install.

13
escapisam

Deux étapes.

1. Ajoutez une nouvelle route dans votre fichier de routes.

// routes/api.php

Route::post('oauth/token', 'AuthController@auth');

Gardez à l'esprit que cela changera l'itinéraire pour obtenir le jeton de /oauth/token à /api/oauth/token.

2. Ajoutez la méthode du contrôleur.

<?php
// app/Http/Controllers/AuthController.php

namespace App\Http\Controllers;

use App\User;
use Psr\Http\Message\ServerRequestInterface;
use \Laravel\Passport\Http\Controllers\AccessTokenController;

class AuthController extends AccessTokenController
{
    public function auth(ServerRequestInterface $request)
    {
            $tokenResponse = parent::issueToken($request);
            $token = $tokenResponse->getContent();

            // $tokenInfo will contain the usual Laravel Passort token response.
            $tokenInfo = json_decode($token, true);

            // Then we just add the user to the response before returning it.
            $username = $request->getParsedBody()['username'];
            $user = User::whereEmail($username)->first();
            $tokenInfo = collect($tokenInfo);
            $tokenInfo->put('user', $user);

            return $tokenInfo;
    }
}
4
Albert Cloete

Une autre meilleure réponse du Web

Personnalisé Laravel Passport BearerTokenResponse

https://Gist.github.com/messi89/489473c053e3ea8d9e034b0032effb1d

2
cyberfly

J'utilise Multi-Auth avec passeport , donc les réponses précédentes ne m'ont pas aidé.

Après des heures de recherche sur Google, j'ai trouvé cette réponse (après-) middleware .

Mon middleware obtient essentiellement le résultat de l'authentification Passport, vérifie s'il y a un porteur à l'intérieur et ajoute plus de données au contenu.

<?php

namespace App\Http\Middleware;

use Closure;

class AppendTokenResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        $response =  $next($request);

        $content = json_decode($response->content(), true);

        if (!empty($content['access_token'])) {

            $content['moredata'] = 'some data';

            $response->setContent($content);

        }

        return $response;
    }
}

Maintenant, mettez le nouveau middleware dans $ routemiddleware sur App/Http/Kernel.php

 /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'cors' => \App\Http\Middleware\Cors::class,
        'multiauth' => \SMartins\PassportMultiauth\Http\Middleware\MultiAuthenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'oauth.providers' => \SMartins\PassportMultiauth\Http\Middleware\AddCustomProvider::class,
        'append_auth' =>\App\Http\Middleware\AppendTokenResponse::class,

    ];

Ensuite, enregistrez simplement ce middleware dans Passport Routes dans Providers/AuthServiceProvider.php

Avec Multiauth:

Route::group(['middleware' => ['oauth.providers','append_auth']], function () {
    Passport::routes(function ($router) {
        return $router->forAccessTokens();
    });
});

Je crois que le passeport ordinaire devrait être (non testé):

Route::group(['middleware' => ['append_auth']], function () {
    Passport::routes();
});
0
Leo Nogueira

Pour ajouter des revendications personnalisées à votre jeton Passport, voici un résumé utilisant Passport 8 avec Laravel 6

https://Gist.github.com/onamfc/0422da15743918e653888441ba6226ca

0
brandon-estrella-dev