Laravel Паспорт - используйте пользовательского провайдера для аутентификации с помощью внешнего API, используя авторизацию запроса на паспорт - PullRequest
0 голосов
/ 20 января 2020

Мне было поручено написать 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) {}
}
...