Мне было поручено написать API, который служит прокси-сервером для другого внешнего API (поскольку к этому API нельзя получить доступ напрямую через браузер из-за CORS), но с собственным уровнем авторизации запросов и аутентификации пользователей.
Я рассматриваю Laravel Паспорт как возможное решение этой проблемы, но мне трудно понять, как авторизация и аутентификация могут быть абстрагированы в пользовательские логи c.
Так , что я хотел бы сделать, это использовать Password Client и отправить имя пользователя и пароль вместе с идентификатором клиента и секретом, я хочу использовать внешний API, чтобы проверить, что имя пользователя и пароль в порядке, но хочу использовать Passport в выдача и аутентификация токенов. Таким образом, основываясь на результате вызова внешнего API, токены выдаются / запрещаются
Я не могу вызвать внешний API напрямую из браузера из-за CORS, поэтому приложение по сути является прокси для другого API. По сути, я не могу использовать таблицу пользователей для проверки предоставленной информации.
Я бы хотел использовать пользовательский провайдер для получения имени пользователя / пароля и аутентификации пользователя с помощью внешнего API перед выдачей токенов с Passport затем можно отправить указанный токен на защищенные маршруты с помощью auth:api
промежуточного программного обеспечения. Возможно ли это?
Вот что мне удалось до сих пор ... Любой совет по этому вопросу будет оценен.
В app/Providers/AuthServiceProvider.php
public function boot()
{
$this->registerPolicies();
Auth::provider('bc', function ($app) {
return new BigcommerceUserProvider($app['bc']);
});
}
В config/auth.php
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'external',
],
],
'providers' => [
'external' => [
'driver' => 'bc',
],
],
В app/Auth/Bigcommerce/UserProvider.php
:
<?php
namespace App\Auth\Bigcommerce;
use Illuminate\Contracts\Auth\UserProvider as UserContract;
use Illuminate\Contracts\Auth\Authenticatable;
use App\Services\Bigcommerce\Bigcommerce;
use Illuminate\Auth\GenericUser;
class UserProvider implements UserContract
{
/**
* Bigcommerce service instance
*
* @var \App\Services\Bigcommerce\Bigcommerce
*/
public $bigcommerce;
/**
* The provider instance.
*
* @param \App\Services\Bigcommerce\Bigcommerce $bigcommerce
* @return void
*/
public function __construct(Bigcommerce $bigcommerce)
{
$this->bigcommerce = $bigcommerce;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
// @note Not implemented yet...
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
try {
$customer = $this->bigcommerce
->setVersion('v3')
->getCustomers([
'email:in' => $credentials['username'],
]);
} catch (\Exception $e) {
return null;
}
if (count($customer) === 0) {
return null;
}
return $this->getGenericUser($customer[0]);
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
try {
$validPassword = $this->bigcommerce
->setVersion('v2')
->validateCustomerPassword($user->getAuthIdentifier(), $credentials['password']);
} catch (\Exception $e) {
return false;
}
return $validPassword['success'] ?? false;
}
/**
* Gets an instance of an generic user.
*
* @param mixed $user
* @return \Illuminate\Auth\GenericUser|null
*/
public function getGenericUser($user)
{
return !is_null($user) ? new GenericUser($user) : null;
}
/**
* Empty methods implemented to satisfy contract
*/
public function retrieveByToken($identifier, $token) {}
public function updateRememberToken(Authenticatable $user, $token) {}
}