Configuring a response to the Laravel Passport token

I'm currently working on an API and hit a brick wall. I am using Passport with a type of type "Password".

I want to return user information using access tokens, however I'm not sure how to do this.

Which class can 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.

+11
source share
5 answers

Instructions on how to do this are described in the BearerTokenResponse class (included in the league / oauth2-server package).

Tested on Laravel 5.7.

1. Extend the BearerTokenResponse class, add additional parameters that 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 to pass 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 automatic detection of laravel in composer.json

This stops loading the default PassportServiceProvider class.

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

Then run composer install .

+5
source

Another best answer from the Internet

Custom Laravel Passport BearerTokenResponse

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

+2
source

Two steps.

1 . Add a new route to the routes file.

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

Remember that this will change the route for getting the token from /oauth/token to /api/oauth/token .

2 . Add a 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; } } 
+1
source

I use Multi-Auth with a passport , so the previous answers did not help me.

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

My middleware basically gets the Passport authentication result, checks to see if there is any Bearer inside, and adds extra 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 in App / Http / Kernel.php

  /** * The application 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 simply register this passport route middleware with Providers / AuthServiceProvider.php

With MultiAuth:

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

I believe that a regular passport should be (not verified):

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

You can do it easily. Open the BearerTokenResponse.php file located in vendor \ league \ oauth2-server \ src \ ResponseTypes

Modify the generateHttpResponse (ResponseInterface $ response) method as follows:

 public function generateHttpResponse(ResponseInterface $response) { $expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp(); $jwtAccessToken = $this->accessToken->convertToJWT($this->privateKey); $responseParams = [ 'token_type' => 'Bearer', 'expires_in' => $expireDateTime - (new \DateTime())->getTimestamp(), 'access_token' => (string) $jwtAccessToken, 'user' => User::find($this->accessToken->getUserIdentifier()), ]; if ($this->refreshToken instanceof RefreshTokenEntityInterface) { $refreshToken = $this->encrypt( json_encode( [ 'client_id' => $this->accessToken->getClient()->getIdentifier(), 'refresh_token_id' => $this->refreshToken->getIdentifier(), 'access_token_id' => $this->accessToken->getIdentifier(), 'scopes' => $this->accessToken->getScopes(), 'user_id' => $this->accessToken->getUserIdentifier(), 'expire_time' => $this->refreshToken->getExpiryDateTime()->getTimestamp(), ] ) ); $responseParams['refresh_token'] = $refreshToken; } $responseParams = array_merge($this->getExtraParams($this->accessToken), $responseParams); $response = $response ->withStatus(200) ->withHeader('pragma', 'no-cache') ->withHeader('cache-control', 'no-store') ->withHeader('content-type', 'application/json; charset=UTF-8'); $response->getBody()->write(json_encode($responseParams)); return $response; } 

Remember to use the App \ User model.

Hope this helps you.

-3
source

Source: https://habr.com/ru/post/1266179/


All Articles