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.
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
.
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;
}
}
Une autre meilleure réponse du Web
Personnalisé Laravel Passport BearerTokenResponse
https://Gist.github.com/messi89/489473c053e3ea8d9e034b0032effb1d
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();
});
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