Как войти с помощью OTP, в Laravel Passport OAuth2 аутентификация - PullRequest
0 голосов
/ 20 марта 2020

Я использую Laravel Паспорт OAuth2 для аутентификации при входе. И он отлично работает с аутентификацией по имени пользователя и паролю. Но я хочу пройти аутентификацию с помощью входа в систему на основе OTP, и я не нашел подходящей документации. Я попробовал следующую ссылку. :

https://medium.com/@arifulislam_ron/create-custom-grant-token-in-laravel-passport-1ff0cc255dc5

Мой код AuthServiceProvider:

use Laravel\Passport\Passport;
use App\Auth\Grants\OtpGrant;
use App\Passport\Bridge\RefereshTokenRepository;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
Use League\OAuth2\Server\AuthorizationServer


#### Boot: 
 $this->registerPolicies();
        app(AuthorizationServer::class)->enableGrantType(
            $this->makeOtpGrant(), Passport::tokensExpireIn()
        );

#### Function: 
protected function makeOtpGrant()
    {
        $grant = new otpGrant(
            $this->app->make(RefreshTokenRepository::class)
        );
        $grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());
        return $grant;
    }

Мое приложение \ Auth \ Grants \ OtpGran Код:

<?php

namespace App\Auth\Grants;

use RuntimeException;
use Illuminate\Http\Request;
use App\Exceptions\OtpException;
use Laravel\Passport\Bridge\User;
use League\OAuth2\Server\RequestEvent;
use App\Http\sapi\Grants\OtpVerifierFactory;
use Psr\Http\Message\ServerRequestInterface;
use League\OAuth2\Server\Grant\AbstractGrant;
use League\OAuth2\Server\Entities\UserEntityInterface;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;

class OtpGrant extends AbstractGrant
{
    /**
     * @param RefreshTokenRepositoryInterface $refreshTokenRepository
     */
    public function __construct(
        RefreshTokenRepositoryInterface $refreshTokenRepository
    ) {
        $this->setRefreshTokenRepository($refreshTokenRepository);

        $this->refreshTokenTTL = new \DateInterval('P1M');
    }

    /**
     * {@inheritdoc}
     */
    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, $client);

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

    protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client)
    {
        $otp = $this->getRequestParameter('otp', $request);
        if (is_null($otp)) {
            throw OAuthServerException::invalidRequest('otp');
        }

        $otpVerifierParam = $this->getRequestParameter('otp_verifier', $request);

        $otpVerifier = OtpVerifierFactory::getOtpVerifier(
                            $this->getRequestParameter('otp_verifier', $request, 'BL_INTERNAL')
                        );

        if ( is_null($otpVerifier) ) {
            throw OtpException::invalidOtpVerifier();
        }

        $isValidOtp = $otpVerifier->verify($otp);

        if (!$isValidOtp){
            throw OtpException::invalidOtp();
        }

        $username = $this->getRequestParameter('username', $request);
        if (is_null($username)) {
            throw OAuthServerException::invalidRequest('username');
        }

        $user = $this->getUserEntityByUserOtp(
            $username,
            $this->getIdentifier(),
            $client
        );

        if ($user instanceof UserEntityInterface === false) {
            $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request));

            throw OAuthServerException::invalidCredentials();
        }

        return $user;
    }

    private function getUserEntityByUserOtp($username, $grantType, ClientEntityInterface $clientEntity)
    {
        $provider = config('auth.guards.api.provider');

        if (is_null($model = config('auth.providers.'.$provider.'.model'))) {
            throw new RuntimeException('Unable to determine authentication model from configuration.');
        }

        $user = (new $model)->where('username', $username)->first();

        if (is_null($user)) {
            return;
        }

        return new User($user->getAuthIdentifier());
    }

    /**
     * {@inheritdoc}
     */
    public function getIdentifier()
    {
        return 'otp_grant';
    } 

    }

Вывод будет выглядеть как:

{
    "message": "Target class [App\\Providers\\RefreshTokenRepository] does not exist.",
    "exception": "Illuminate\\Contracts\\Container\\BindingResolutionException",
    "file": "C:\\xampp\\htdocs\\onesapi\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
    "line": 805,
    "trace": [
        {
            "file": "C:\\xampp\\htdocs\\onesapi\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
            "line": 681,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
После использования этого кода возникает одна и та же проблема для всех аутентификаций apis

Ожидаемый результат:

{
    "token": {
        "token_type": "Bearer",
        "expires_in": 10367998,
        "access_token": "__ Access Token Key",
        "refresh_token": "__ Refresh token key"
    },

Если у кого-нибудь есть идея по аутентификации входа в систему на основе OTP, пожалуйста, помогите мне.

Спасибо Вы

...