Customising token response Laravel Passport

后端 未结 5 1482
被撕碎了的回忆
被撕碎了的回忆 2020-12-16 11:34

I am working on an API at the moment and have hit a brick wall. I am using Passport with the \'Password\' grant type.

I want to return the user information with the

相关标签:
5条回答
  • 2020-12-16 11:51

    Another better answer from the web

    Custom Laravel Passport BearerTokenResponse

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

    0 讨论(0)
  • 2020-12-16 11:53

    The instructions on how to do this are hinted in the BearerTokenResponse class (part of the league/oauth2-server package).

    Tested on Laravel 5.7.

    1. Extend the BearerTokenResponse class, add the extra params you need in the response.

    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. Create your own PassportServiceProvider class and override the makeAuthorizationServer() method in order to pass in your own BearerTokenResponse class.

    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. Add your provider to the providers array in config/app.php

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

    4. Exclude the passport package from laravel auto-discovery in composer.json

    This stops the default PassportServiceProvider class from being loaded.

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

    Then run composer install.

    0 讨论(0)
  • 2020-12-16 11:58

    Im using Multi-Auth with passport, so the previous answers didn't help me.

    After hours of "googling" I found this answer (after-) middleware.

    My middleware basically gets the result of Passport auth, checks if there is an Bearer inside and append more data to the content.

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

    Now put the new Middleware in $routemiddleware at 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,
    
        ];
    

    Then just register this middleware to Passport Routes in Providers/AuthServiceProvider.php

    With Multiauth:

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

    I believe regular passport should be (not tested):

    Route::group(['middleware' => ['append_auth']], function () {
        Passport::routes();
    });
    
    0 讨论(0)
  • 2020-12-16 11:59

    To add custom claims to your Passport token, here is a gist using Passport 8 with Laravel 6

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

    0 讨论(0)
  • 2020-12-16 12:05

    Two steps.

    1. Add a new route in your routes file.

    // routes/api.php
    
    Route::post('oauth/token', 'AuthController@auth');
    

    Keep in mind this will change the route for getting the token from /oauth/token to /api/oauth/token.

    2. Add the controller method.

    <?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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题