Параболические паспорта Laravel и пассы api

Я использую Laravel Framework версии 5.3.9, новая загрузка ничего не добавляется через композитора (кроме "laravel/passport": "^1.0" ).

Я сделал все, что было предложено в документах . Создаются таблицы, маршруты вверх, все работает нормально. Однако мне нужен паспорт для API.

Мои маршруты выглядят так:

 +--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/v1/users/register | api::users::register | App\Http\Controllers\Api\V1\SocialController@register | api,auth | | | POST | oauth/authorize | | \Laravel\Passport\Http\Controllers\ApproveAuthorizationController@approve | web,auth | | | GET|HEAD | oauth/authorize | | \Laravel\Passport\Http\Controllers\AuthorizationController@authorize | web,auth | | | DELETE | oauth/authorize | | \Laravel\Passport\Http\Controllers\DenyAuthorizationController@deny | web,auth | | | GET|HEAD | oauth/clients | | \Laravel\Passport\Http\Controllers\ClientController@forUser | web,auth | | | POST | oauth/clients | | \Laravel\Passport\Http\Controllers\ClientController@store | web,auth | | | PUT | oauth/clients/{client_id} | | \Laravel\Passport\Http\Controllers\ClientController@update | web,auth | | | DELETE | oauth/clients/{client_id} | | \Laravel\Passport\Http\Controllers\ClientController@destroy | web,auth | | | GET|HEAD | oauth/personal-access-tokens | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser | web,auth | | | POST | oauth/personal-access-tokens | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store | web,auth | | | DELETE | oauth/personal-access-tokens/{token_id} | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy | web,auth | | | GET|HEAD | oauth/scopes | | \Laravel\Passport\Http\Controllers\ScopeController@all | web,auth | | | POST | oauth/token | | \Laravel\Passport\Http\Controllers\AccessTokenController@issueToken | | | | POST | oauth/token/refresh | | \Laravel\Passport\Http\Controllers\TransientTokenController@refresh | web,auth | | | GET|HEAD | oauth/tokens | | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser | web,auth | | | DELETE | oauth/tokens/{token_id} | | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy | web,auth | +--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+ 

Все web маршруты есть, нет связанных с api маршрутов, так как Passport не предоставляет ничего подобного из коробки.

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

Как только пользователь получает доступ к маршруту /register , сам процесс регистрации достаточно прост: получить доступ к учетной записи пользователя facebook, чтобы захватить несколько полей – адрес электронной почты, идентификатор facebook, имя изображения профиля, и с этого момента пользователи считаются зарегистрированными. Но пользователь НЕ войдет в систему с facebook (это очень важный аспект). В потребительском приложении будет выпущен токен и он будет использовать этот токен для доступа к различным конечным точкам api (для которых требуется использовать токен).

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

Пока Паспорт является головной болью, с которой нужно работать, когда дело доходит до реализации связанных с API материалов, либо это, либо я не могу понять, как заставить его работать правильно.

Я создал тестовый клиент в таблице oauth_clients который выглядит так:

введите описание изображения здесь

Я использую Postman для доступа к api/v1/users/register route, у которого есть промежуточное ПО auth со следующим JSON application/json

 { "grant_type" : "authorization_code", "client_id" : 5, "client_secet": "y5dvPIOxQJOjYn7w2zzg4c6TRrphsrNFWbG4gAUL" } 

Это, конечно, приведет к

 {"error":"Unauthenticated."} 

Это имеет смысл. Из чистого любопытства я изменил маршрут /register :

 Route::group([ 'middleware' => [ ], ], function () { Route::group([ 'prefix' => 'users', 'as' => 'users::', ], function () { // Route::get('/register', ['as' => 'register', 'uses' => 'Api\V1\SocialController@register',]); Route::post('/register', ['as' => 'register', 'uses' => '\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken',]); }); }); 

С тем же json что и раньше. Это привело к {"error":"invalid_client","message":"Client authentication failed"} .

Я отслеживаю функцию, которая, я думаю, обрабатывает часть validateClient в vendor/league oauth2-server / src / Grant / AbstractGrant` .

$client имеет значение null. Теперь это может быть или не быть связано с Паспортом, поскольку документация на нем скорее отсутствует и мысль о том, чтобы выкапывать через монстра пакета, чтобы отследить ошибку, которая может быть в значительной степени из-за того, что я не делаю что-то правильно, не ударяет меня как хорошая идея, у меня нет вариантов. Честно говоря, я даже не знаю, в чем проблема.

Действительно, в этот момент любой вид, указывающий в правильном направлении, более чем приветствуется.

Часть вопросов

Related of "Параболические паспорта Laravel и пассы api"

Проблема с паспортом Laravel 5.3 заключается в том, что в отличие от предыдущего сервера OAuth 2.0 для библиотеки Laravel, предлагаемого lucadegasperi, у него нет API для непосредственного создания клиентов. Так что, если теперь клиент может быть сделан только через интерфейс. FYI мы хотели использовать паспорт laravel исключительно для нашего мобильного приложения, поэтому при создании и регистрации пользователя у нас будет только EMAIL & Password, а в некоторых случаях только Facebook UserID для входа в facebook. Таким образом, следующий подход работал очень хорошо для нашего случая и может отличаться для вашего сценария, но может помочь вам в более долгосрочной перспективе поиграть с паспортом laravel.

Примечание. Прежде чем следовать ниже, предполагается, что вы включили «Пароль» в своем приложении.

Таким образом, мы решили это для нашего проекта на laravel 5.3:

  1. в oauth_clients преобразуют поле id в нормальное поле, то есть удаляют его как первичный ключ и делают тип данных как varchar, чтобы мы могли хранить адрес электронной почты как client_ids, поскольку они также уникальны для вашей системы. В случае входа в Facebook мы храним идентификаторы пользователей Facebook здесь, в этом столбце, который снова будет уникальным для каждого нашего клиента. Также для других таблиц, таких как: oauth_access_tokens, oauth_auth_codes и oauth_personal_access_clients изменяет client_id на VARCHAR (255), чтобы он мог хранить адреса электронной почты или идентификаторы пользователей Facebook.

  2. Теперь перейдите к вашим моделям и создайте модель для таблицы oauth_clients, чтобы вы могли программно создавать клиентский код из кода при создании пользователей.

     <?php namespace App; use Illuminate\Database\Eloquent\Model; class OauthClient extends Model { protected $table = 'oauth_clients'; } 
  3. Затем в файле маршрута api.php добавьте следующий маршрут:

     Route::post('/register-user', function (Request $request) { $name = $request->input('name'); $email = $request->input('email'), $password = $request->input('password'), // save new user $user = \App\User::create([ 'name' => $name, 'email' => $email, 'password' => bcrypt($password), ]); // create oauth client $oauth_client = \App\OauthClient::create([ 'user_id' => $user->id, 'id' => $email, 'name' => $name, 'secret' => base64_encode(hash_hmac('sha256',$password, 'secret', true)), 'password_client' => 1, 'personal_access_client' => 0, 'redirect' => '', 'revoked' => 0, ]); return [ 'message' => 'user successfully created.' ]; }); 

В приведенном выше фрагменте кода вы должны заметить, что для генерации секретного ключа oauth_client вы должны использовать сильную формулу шифрования, которую вы чувствуете комфортно, используя ее с вашим приложением. Кроме того, используйте тот же метод для создания секретного ключа в мобильном приложении для соответствующего клиента / пользователя.

  1. Теперь вы можете использовать стандартный API POST, предлагаемый паспортом laravel, для запроса токена доступа через предоставление пароля с помощью «oauth / token», используя следующие параметры:

     grant_type : 'password' client_id : '<email with which the user is registered>' client_secret : '<generate the client secret from the mobile app>' username : '<email with which the user is registered>' password : '<password entered by the user>' scope : '<leave empty as default>' 
  2. Вышеприведенный ответ даст вам ответ, если все будет правильно, аналогично:

     { "token_type": "Bearer", "expires_in": 3155673600, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3In0.eyJhdWQiOiJzaHVqYWhtQGdtYWlsLmNvbSIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3IiwiaWF0IjoxNDc4MTQ1NjMyLCJuYmYiOjE0NzgxNDU2MzIsImV4cCI6NDYzMzgxOTIzMiwic3ViIjoiMSIsInNjb3BlcyI6W119.dj3g9b2AdPCK-im5uab-01SP71S7AR96R0FQTKKoaZV7M5ID1pSXDlmZw96o5Bd_Xsy0nUqFsPNRQsLvYaOuHZsP8v9mOVirBXLIBvPcBc6lDRdNXvRidNqeh4JHhJu9a5VzNlJPm3joBYSco4wYzNHs2BPSxXuuD3o63nKRHhuUHB-HwjVxj2GDwzEYXdZmf2ZXOGRJ99DlWGDvWx8xQgMQtd1E9Xk_Rs6Iu8tycjBpKBaC24AKxMI6T8DpelnFmUbMcz-pRsgCWCF_hxv6FpXav3jr1CLhhT58_udBvXjQAXEbtHeB7W_oaMcaqezHdAeOWDcnqREZHsnXHtKt0JpymcTWBkS2cg7sJzy6P9mOGgQ8B4gb8wt44_kHTeWnokk4yPFRZojkHLVZb8YL6hZxLlzgV1jCHUxXoHNe1VKlHArdlV8LAts9pqARZkyBRfwQ8oiTL-2m16FQ_qGg-9vI0Suv7d6_W126afI3LxqDBi8AyqpQzZX1FWmuJLV0QiNM0nzTyokzz7w1ilJP2PxIeUzMRlVaJyA395zq2HjbFEenCkd7bAmTGrgEkyWM6XEq1P7qIC_Ne_pLNAV6DLXUpg9bUWEHhHPXIDYKHS-c3N9fPDt8UVvGI8n0rPMieTN92NsYZ_6OqLNpcm6TrhMNZ9eg5EC0IPySrrv62jE", "refresh_token": "BbwRuDnVfm7tRQk7qSYByFbQKK+shYPDinYA9+q5c/ovIE1xETyWitvq6PU8AHnI5FWb06Nl2BVoBwCHCUmFaeRXQQgYY/i5vIDEQ/TJYFLVPRHDc7CKILF0kMakWKDk7wJdl5J6k5mN38th4pAAZOubiRoZ+2npLC7OSZd5Mq8LCBayzqtyy/QA5MY9ywCgb1PErzrGQhzB3mNhKj7U51ZnYT3nS5nCH7iJkCjaKvd/Hwsx2M6pXnpY45xlDVeTOjZxxaOF/e0+VT2FP2+TZMDRfrSMLBEkpbyX0M/VxunriRJPXTUvl3PW0sVOEa3J7+fbce0XWAKz7PNs3+hcdzD2Av2VHYF7/bJwcDCO77ky0G4JlHjqC0HnnGP2UWI5qR+tCSBga7+M1P3ESjcTCV6G6H+7f8SOSv9FECcJ8J5WUrU+EHrZ95bDtPc9scE4P3OEQaYchlC9GHk2ZoGo5oMJI6YACuRfbGQJNBjdjxvLIrAMrB6DNGDMbH6UZodkpZgQjGVuoCWgFEfLqegHbp34CjwL5ZFJGohV+E87KxedXE6aEseywyjmGLGZwAekjsjNwuxqD2QMb05sg9VkiUPMsvn45K9iCLS5clEKOTwkd+JuWw2IU80pA24aXN64RvOJX5VKMN6CPluJVLdjHeFL55SB7nlDjp15WhoMU1A=" } 

Его единственное временное решение до тех пор, пока laravel не поддерживает внешний API для приложений, у которых есть только мобильный телефон, как единственный возможный интерфейс для создания клиентов и пользователей OAuth.

Надеюсь, это поможет вам! Приветствия.

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

  1. Вы почти НИКОГДА не хотите размещать логику процесса сервера такого типа в своем каталоге маршрутов. Особенно при работе над созданием API с целью его ввода в производство. Это грязный маршрут, который нужно взять и не совсем безопасно. UNLESS это для вещей, которые безопасны для обработки в вашем каталоге маршрутов. Как, в меньшем масштабе, базовая логика для отправки уведомления (SMS, электронная почта, push, slack) сотрудникам о новом письме / блоге / заметке, публикуемом в качестве примера.

  2. ВСЕГДА пытайтесь использовать и использовать как можно больше возможностей фреймворка, прежде чем пытаться «хакерски» выполнить задачу, которая, возможно, была выполнена несколько раз раньше.

  3. Убедитесь, что вы делаете правильные исследования о том, что уже сделано. Таким образом, упрощается просто ссылка на видео или учебник, в котором показано, как правильно делать то, что кто-то пытается сделать.

При этом хорошей отправной точкой будет просмотр следующего видео, которое прекрасно описывает основы правильной настройки того, что вы хотите настроить:

https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/13

Во многих отношениях, видео-учебник очень хорошо сделан и тщательно от начала до конца. Обязательно воспользуйтесь другими Grant_Types для OAuth2.0, чтобы вы могли лучше понять, какой конкретный тип вам / вашему приложению нужен на основе позиции вашего приложения, чтобы потреблять api:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Кроме того, не забудьте использовать доступные функции laravel для входа и регистрации при создании или входе в систему пользователей. Контроллеры созданы для вас, когда вы выполняете следующие действия в консоли:

 php artisan make:auth 

Кроме того, если паспорт – это что-то загадочное, вы всегда можете найти пакет laravel / socialite ( https://github.com/laravel/socialite ). Это позволит вам «Войти в систему (Social Network Here)». При условии, что это маршрут, к которому вы также хотите отправиться.

ЗАМЕЧАНИЕ КОНЕЦ: Часть, которую я видел в вашем вопросе, которая больше всего зависела от того, как человек зарегистрируется, но не войдет в систему с facebook. Вместо этого будет иметь токен доступа для доступа к различным конечным точкам API. Поэтому, если я получаю то, что вы говорите правильно, вы пытаетесь использовать данные пользователя из facebook, когда данные возвращаются, пользователь считается зарегистрированным и должен получить токен доступа. ТАК:

  1. Используйте socialite, чтобы отправить запрос «login with facebook» в facebook. Это позволит получить данные пользователя и использовать несколько способов аутентификации в facebook.

  2. Когда запрос возвращается с пользовательскими данными внутри тела, запустите его с помощью проверки, чтобы убедиться, что есть данные (просто если оператор должен быть точным). Поскольку facebook уже аутентифицировал пользователя и отправил учетные данные, вам должно быть хорошо идти.

  3. Вы можете либо отключить внутренний прокси-сервер в своем контроллере входа (который является более чистым и безопасным способом его выполнения), либо вы можете выпустить JWT (который покрывается за последние 5 минут видео, опубликованного в этом ответе выше).

    Ниже приведен пример кода для начала работы.

    App \ Http \ Контроллеры \ Auth \ LoginController.php

     class LoginController extends Controller { // ... protected function authenticateClient(Request $request) { $credentials = $this->credentials($request); $data = $request->all(); $user = User::where('email', $credentials['email'])->first(); $request->request->add([ 'grant_type' => $data['grant_type'], 'client_id' => $data['client_id'], 'client_secret' => $data['client_secret'], 'username' => $credentials['email'], 'password' => $credentials['password'], 'scope' => null, ]); $proxy = Request::create( 'oauth/token', 'POST' ); return Route::dispatch($proxy); } protected function authenticated(Request $request, $user) { return $this->authenticateClient($request); } protected function sendLoginResponse(Request $request) { $request->session()->regenerate(); $this->clearLoginAttempts($request); return $this->authenticated($request, $this->guard()->user()); } public function login(Request $request) { if ($this->guard('api')->attempt($credentials, $request->has('remember'))) { return $this->sendLoginResponse($request); } } } 

Приведенный выше код используется В СЛУЧАЕ, что вы пытаетесь использовать тип пароля для аутентификации клиентов через паспорт. Тем не менее, я бы серьезно посмотрел видеоролик, прежде чем прыгать с пистолета на что угодно. Это поможет вам много узнать, как использовать laravel 5.3 с паспортом.