【问题标题】:What is the proper way to implement a custom Laravel passport grant?实施自定义 Laravel 护照授予的正确方法是什么?
【发布时间】:2019-12-24 22:16:02
【问题描述】:

我一直在修改 laravel 护照,但我似乎无法实现自定义授权类型。我正在使用 laravel 5.6 和护照 6.0 。 经过研究,我在CustomGrant library 中同样创建了一个 CustomRequestGrantProvider 和一个 CustomRequestGrant 但我没有运气,每次我都会向 localhost 发出 POST 请求: 8000/oauth/tokengrant_type、client_idclient_secret

{"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check that all required parameters have been provided"}

看来,我的请求甚至没有通过。 我确保将提供程序添加到 app.php

这是我的 CustomRequestGrantProvider

class CustomRequestGrantProvider extends PassportServiceProvider{


public function boot()
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'passport');
    $this->deleteCookieOnLogout();


}

public function register()
{
    $this->registerAuthorizationServer();
}

protected function registerAuthorizationServer()
{
    $this->app->singleton(AuthorizationServer::class, function () {
        return tap($this->makeAuthorizationServer(), function ($server) {
            $server->enableGrantType(
                $this->makeCustomRequestGrant(), Passport::tokensExpireIn()
            );
        });
    });
}

protected function makeCustomRequestGrant()
{
    $grant = new CustomRequestGrant(
        $this->app->make(UserRepository::class),
        $this->app->make(RefreshTokenRepository::class)
    );
    $grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());
    return $grant;
}}

这是我的 CustomRequestGrant

class CustomRequestGrant extends AbstractGrant{

public function __construct(
    UserRepositoryInterface $userRepository,
    RefreshTokenRepositoryInterface $refreshTokenRepository
)
{
    $this->setUserRepository($userRepository);
    $this->setRefreshTokenRepository($refreshTokenRepository);
    $this->refreshTokenTTL = new \DateInterval('P1M');
}

public function respondToAccessTokenRequest(
    ServerRequestInterface $request,
    ResponseTypeInterface $responseType,
    \DateInterval $accessTokenTTL
)
{
    // Validate request
    $client = $this->validateClient($request);
    $scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
    $user = $this->validateUser($request);
    // Finalize the requested scopes
    $scopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier());
    // Issue and persist new tokens
    $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $scopes);
    $refreshToken = $this->issueRefreshToken($accessToken);
    // Inject tokens into response
    $responseType->setAccessToken($accessToken);
    $responseType->setRefreshToken($refreshToken);
    return $responseType;
}

public function getIdentifier()
{
    return 'custom_request';
}

protected function validateUser(ServerRequestInterface $request)
{
    $laravelRequest = new Request($request->getParsedBody());
    $user = $this->getUserEntityByRequest($laravelRequest);
    if ($user instanceof UserEntityInterface === false) {
        $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request));
        throw OAuthServerException::invalidCredentials();
    }
    return $user;
}

protected function getUserEntityByRequest(Request $request)
{
    if (is_null($model = config('auth.providers.users.model'))) {
        throw OAuthServerException::serverError('Unable to determine user model from configuration.');
    }
    if (method_exists($model, 'byPassportCustomRequest')) {
        $user = (new $model)->byPassportCustomRequest($request);
    } else {
        throw OAuthServerException::serverError('Unable to find byPassportCustomRequest method on user model.');
    }
    return ($user) ? new User($user->id) : null;
}} 

注意:所有导入和命名空间都是正确的,我只是为了这篇文章而删除了它们。

我什至考虑过编辑护照库,但我不确定它在未来的可持续性如何。

非常感谢任何帮助。

一些参考资料:

Custom Grants?

Outdated custom grant example

Github discussion

【问题讨论】:

    标签: laravel laravel-5 laravel-5.6 laravel-passport laravel-5.7


    【解决方案1】:

    所以我最终创建了实现原始类的自定义类(请看下图)

    laravel/passport trait 所需的类是下图中的类,开头没有 Custom

    对于CustomUserRepositoryInterface,你只需要修改UserRepositoryInterface,例如你需要向laravel post请求发送一个额外的参数。

    这使我能够大量自定义 laravel 护照,例如传递具有不同访问应用程序的多种帐户类型(例如使用电话号码、电子邮件、facebook_token 和 id 登录)。

    很抱歉,我没有深入了解答案,但我正在考虑创建一个库并在 github 上分享我的工作,当然更新答案并分享链接,但至少,这些是唯一的你需要改变类来达到这样的结果。

    祝你有美好的一天:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多