Поток предоставления паролей Laravel Passport для сторонних приложений

Я использую Паспорт Laravel, чтобы предоставить доступ к некоторым частям моего API сторонним приложениям.

Но я также использую свой собственный API через собственное собственное приложение для Android. Итак, я просмотрел весь Интернет в поисках лучших практик в этом случае, но застрял, чтобы сделать вывод.

Вот возможности, которые я обнаружил:

Возможность # 01

Я могу следить за Поток предоставления пароля для учетных данных пользователя.
В этом случае мне нужно передать client_secret и client_id серверу авторизации. Чтобы сохранить их в безопасности, я не могу записать их в исходный код своего мобильного приложения (APK-файлы декомпилируются ...).

Итак, у меня есть 2 варианта.

Возможность # 01 - Вариант А

Проксификация через мой собственный сервер и ввод секрета перед вызовом конечной точки oauth:

$proxy = Request::create('/oauth/token', 'post', [
    'grant_type' => 'password',
    'client_id' => 1,
    'client_secret' => 'myownclientsecretishere',
    'username' => $username,
    'password' => $password
]);
$proxy->headers->set('Accept', 'application/json');
$response = app()->handle($proxy);

Возможность # 01 - Вариант B

Внедрите секрет при вызове конечной точки oauth с помощью ПО промежуточного слоя:

class InjectPasswordGrantSecret
{
    public function handle($request, Closure $next)
    {
        $request->request->add([
            'client_id' => 1,
            'client_secret' => 'myownclientsecretishere'
        ]);
        return $next($request);
    }
}

Это рабочие примеры, но они также скупы на ресурсы .. Я попытался использовать Тест Apache на своем локальном компьютере и получил около 9 запросов в секунду.

Возможность # 02

Я могу следить за Грант персонального доступа.
Этот не похож на стандарт в OAuth2, он позволяет нам создавать токен через любой настраиваемый маршрут, вот так:

if (! auth()->attempt(compact('username', 'password'))) {
    return error_response(__('auth.failed'));
}
$user = auth()->user();
$token = $user->createToken(null)->accessToken;

Используя Тест Apache, я получаю лучший результат (примерно 30 запросов в секунду).

Но время жизни токена не настраивается по умолчанию и установлено на 1 год (обратите внимание, что существуют обходные пути, чтобы настроить этот срок службы с помощью настраиваемого поставщика).

Мне действительно интересно, предназначено ли это решение для использования в производственной среде.

Изначально я использовал библиотеку JWT Tymon, потому что у меня было только собственное приложение. Но теперь, когда мне нужно заставить его работать со сторонними и сторонними приложениями, я подумал, что OAuth2 (через Laravel Passport) будет хорошим решением ...

Я надеюсь, что кто-нибудь сможет мне помочь с этим и объяснить, что могло бы быть хорошим решением, чтобы заставить его работать надежно и [не медленно] на производственных серверах.

Вы пробовали laravel.com/docs/5.7/passport#token-lifetimes? Я думаю, что это применимо к токенам предоставления личных данных и пароля.

Ali Farhoudi 30.10.2018 07:29

Проверьте это: github.com/laravel/passport/issues/162#issuecomment-31915779‌ 3

Ali Farhoudi 30.10.2018 07:31

@AliFarhoudi Как я уже сказал (ваша ссылка подтверждает это). Срок действия разрешения на личный доступ можно настроить с помощью специального поставщика (временное решение). Это причина, по которой я не уверен, что мне следует использовать это для своего собственного Android-приложения в производстве.

Marc 30.10.2018 10:04

Нечего беспокоиться о кастомном провайдере. Когда фреймворк этого не учел, вы можете реализовать это по своему усмотрению.

Ali Farhoudi 30.10.2018 16:02

Глядя на ссылки в вашем вопросе, я считаю, что вы используете Laravel 5.7?

Fabian Bettag 14.07.2020 11:55

Да именно в это время

Marc 14.07.2020 19:58

@Marc В этом случае я бы сказал, если возможно, обновитесь до 6, поэтому вы можете просто использовать Passport::personalAccessTokensExpireIn в AuthServiceProvider.

Wouter Florijn 06.11.2020 12:36

почему бы не использовать учетные данные клиента для приложений сторонних производителей?

Cameron 12.11.2020 02:38

Possibility #01 B действительно лучший IMO, я не думаю, что производительность должна быть хуже, чем Possibility #02, в конце концов, нет прокси, и оба создают токен одинаково, и в этом случае это просто означает, что есть некоторые накладные расходы от laravel oauth api

Tofandel 06.04.2021 20:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
29
9
3 095
2

Ответы 2

То, что я сделал раньше, реализовал мой собственный контроллер, расширяющий Laravel\Passport\Http\Controllers\AccessTokenController. Вы можете не только настроить этот контроллер для обработки создания токенов, но также добавить маршруты для обновления и отзыва токенов.

Например, у меня был метод create для отображения формы входа в систему, метод store для создания токена доступа, метод refresh для использования токена обновления для обновления истекших токенов доступа и метод revoke для отзыва предоставленного токена доступа и связанного обновления. токен.

Я не могу предоставить точный код, поскольку проект не является открытым исходным кодом, но это быстрый пример контроллера с использованием только метода store:

use Illuminate\Http\Request;
use Psr\Http\Message\ServerRequestInterface;
use Laravel\Passport\Http\Controllers\AccessTokenController;

class MyAccessTokenController extends AccessTokenController
{
    public function store(Request $request, ServerRequestInterface $tokenRequest)
    {
        // update the request to force your grant type, id, secret, and scopes
        $request->request->add([
            'grant_type' => 'password',
            'client_id' => 'your-client-id',
            'client_secret' => 'your-client-secret',
            'scope' => 'your-desired-scopes',
        ]);

        // generate the token
        $token = $this->issueToken($tokenRequest->withParsedBody($request->request->all()));

        // make sure it was successful
        if ($token->status() != 200) {
            // handle error
        }

        // return the token
        return $token;
    }
}

Метод refresh в основном будет таким же, но grant_type будет refresh_token.

Метод revoke получит токен авторизованного пользователя ($token = $request->user()->token(), отзовет его ($token->revoke()), а затем вручную просмотрит таблицу oauth_refresh_tokens для связанных токенов (access_token_id = $token->id) и обновит поле revoked до true.

Создайте несколько маршрутов для использования вашего настраиваемого контроллера, и все готово (NB: для маршрута revoke потребуется промежуточное ПО auth:api).

Итак, насколько я понимаю, в вашем решении вы добавляете данные в свой запрос (секреты, grant_type ..) для выдачи токенов (используя метод issueToken, который поступает из AccessTokenController), избегая затем дополнительного HTTP-запроса? [по сравнению с моим решением 1a]

Marc 08.11.2018 09:33

Можете ли вы объяснить, что делает это лучше, чем просто использование Personal Access Grant или другое решение?

Marc 08.11.2018 09:35

Вот страница, на которую я всегда ссылаюсь: https://oauth2.thephpleague.com/authorization-server/which-grant/

Это говорит

We strongly recommend that you use the Authorization Code flow over the Password grant for several reasons. We eliminate the password grant option.

Затем на диаграмме четко указано, что вы должны использовать

Authorization Code Grant with PKCE

а также указывает, что

If the client is a web application that has runs entirely on the front end (e.g. a single page web application) or a native application such as a mobile app you should implement the authorization code grant with the PKCE extension. You can read further in the document.

Кроме того, здесь есть хороший учебник, объясняющий каждую деталь потока на примере: https://auth0.com/docs/architecture-scenarios/mobile-api

Надеюсь, это поможет.

PS: Когда мне потребовалось время для авторизации пользователей в моем первом приложении, я использовал предоставление пароля, ссылаясь на эту самую диаграмму. Однако похоже, что это изменилось, и предоставление пароля теперь больше не является лучшей практикой и не рекомендуется.

Другие вопросы по теме