Подтвердить что ты не робот

Паспорт и пассаж Laravel 5.3

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

Я сделал все, что было предложено в docs. Создаются таблицы, маршруты вверх, все работает нормально. Однако мне нужен паспорт для 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\[email protected]                      | api,auth   |
|        | POST     | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\Appro[email protected]  | web,auth   |
|        | GET|HEAD | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\[email protected]       | web,auth   |
|        | DELETE   | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\[email protected]        | web,auth   |
|        | GET|HEAD | oauth/clients                           |                      | \Laravel\Passport\Http\Controllers\[email protected]                | web,auth   |
|        | POST     | oauth/clients                           |                      | \Laravel\Passport\Http\Controllers\[email protected]                  | web,auth   |
|        | PUT      | oauth/clients/{client_id}               |                      | \Laravel\Passport\Http\Controllers\[email protected]                 | web,auth   |
|        | DELETE   | oauth/clients/{client_id}               |                      | \Laravel\Passport\Http\Controllers\[email protected]                | web,auth   |
|        | GET|HEAD | oauth/personal-access-tokens            |                      | \Laravel\Passport\Http\Controllers\[email protected]   | web,auth   |
|        | POST     | oauth/personal-access-tokens            |                      | \Laravel\Passport\Http\Controllers\[email protected]     | web,auth   |
|        | DELETE   | oauth/personal-access-tokens/{token_id} |                      | \Laravel\Passport\Http\Controllers\[email protected]   | web,auth   |
|        | GET|HEAD | oauth/scopes                            |                      | \Laravel\Passport\Http\Controllers\[email protected]                     | web,auth   |
|        | POST     | oauth/token                             |                      | \Laravel\Passport\Http\Controllers\[email protected]        |            |
|        | POST     | oauth/token/refresh                     |                      | \Laravel\Passport\Http\Controllers\[email protected]        | web,auth   |
|        | GET|HEAD | oauth/tokens                            |                      | \Laravel\Passport\Http\Controllers\[email protected] | web,auth   |
|        | DELETE   | oauth/tokens/{token_id}                 |                      | \Laravel\Passport\Http\Controllers\[email protected] | web,auth   |
+--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+

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

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

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

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

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

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

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

Я использую Postman для доступа к маршруту api/v1/users/register, у которого есть промежуточное ПО 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\[email protected]',]);
        Route::post('/register', ['as'   => 'register', 'uses' => '\Laravel\Passport\Http\Controllers\[email protected]',]);
    });

});

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

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

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

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

Частью в вопросах является

4b9b3361

Ответ 1

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

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

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

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

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

    <?php
    namespace App;
    
    
    use Illuminate\Database\Eloquent\Model;
    
    class OauthClient extends Model
    {
        protected $table = 'oauth_clients';
    }
    
  • Затем в файле маршрута 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.

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

Ответ 2

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

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

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

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

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

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, когда данные возвращаются, пользователь считается зарегистрированным и должен быть выпущен токен доступа. SO:

  • Используйте socialite для отправки запроса "login with facebook" на facebook. Это позволит получить пользовательские данные и использовать немного аутентификации в facebook.

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

  • Вы можете отключить внутренний прокси в своем контроллере входа (который является более чистым и безопасным способом его выполнения), или вы можете выпустить 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 с паспортом.