自定义令牌响应 Laravel Passport

问题描述 投票:0回答:6

我目前正在开发 API,但遇到了困难。我正在使用带有“密码”授予类型的 Passport。

我想用访问令牌返回用户信息,但是,我不知道如何做。

我可以实现、编辑或扩展哪个类来获得这个?.

我希望将其退回:

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

提前致谢。

laravel oauth-2.0 laravel-passport
6个回答
27
投票

有关如何执行此操作的说明在

BearerTokenResponse
类(league/oauth2-server 包的一部分)中暗示。

在 Laravel 5.7 上测试。

1。扩展

BearerTokenResponse
类,在响应中添加您需要的额外参数

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。创建您自己的

PassportServiceProvider
类并重写
makeAuthorizationServer()
方法,以便传入您自己的
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.将您的提供商添加到

config/app.php

中的提供商数组中
    /*
     * Application Service Providers...
     */
    App\Providers\PassportServiceProvider::class,

4。从 laravel 自动发现中排除

composer.json

中的 Passport 包

这会停止加载默认的

PassportServiceProvider
类。

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

然后运行

composer install


12
投票

两步。

1在路线文件中添加新路线。

// routes/api.php

Route::post('oauth/token', 'AuthController@auth');

请记住,这会将获取令牌的路线从

/oauth/token
更改为
/api/oauth/token

2添加控制器方法。

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

3
投票

我正在使用带有护照的多重身份验证,所以之前的答案对我没有帮助。

经过几个小时的“谷歌搜索”后,我找到了这个答案(后)中间件

我的中间件基本上获取 Passport auth 的结果,检查里面是否有 Bearer 并将更多数据附加到内容中。

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

现在将新的中间件放入 App/Http/Kernel.php 的 $routemiddleware 中

 /**
     * 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,

    ];

然后只需将此中间件注册到 Providers/AuthServiceProvider.php 中的 Passport Routes

使用多重身份验证:

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

我认为普通护照应该(未测试):

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

2
投票

来自网络的另一个更好的答案

自定义 Laravel Passport BearerTokenResponse

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


2
投票

要将自定义声明添加到您的 Passport 令牌,这里是使用 Passport 8 和 Laravel 6 的要点

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


0
投票

在 Laravel 11 和 Passport 12 中,有一个非常简单的解决方案。

创建新的令牌响应类:

<?php

namespace App\Model;

use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;

class UserBearerTokenResponse extends BearerTokenResponse
{
    protected function getExtraParams(AccessTokenEntityInterface $accessToken): array
    {
        return [
            'user_id' => $accessToken->getUserIdentifier(),
        ];
    }
}

然后在服务提供商(AppServiceProvider 或 AuthServiceProvider 或创建您自己的)中:

Passport::$authorizationServerResponseType = new UserBearerTokenResponse;

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.