Я использую 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, пожалуйста, помогите мне.
Спасибо Вы