Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customising token response Laravel Passport

Tags:

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.

like image 265
Irvin Chan Avatar asked Mar 31 '17 18:03

Irvin Chan


2 Answers

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.

like image 175
escapisam Avatar answered Sep 17 '22 15:09

escapisam


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;     } } 
like image 21
Albert Cloete Avatar answered Sep 17 '22 15:09

Albert Cloete