Customising token response Laravel Passport

Irvin Chan picture Irvin Chan · Mar 31, 2017 · Viewed 15.5k times · Source

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 access tokens, however, I am not sure how to.

Which class could I implement, edit or extend to get this?.

I would like this to be returned:

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

Thanks in advance.

Answer

escapisam picture escapisam · Jan 4, 2019

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.