Рубрики
Uncategorized

[учебник] restful API с использованием аутентификации JWT в laravel

Автор оригинала: David Wong.

Эта статья переслана из профессионального сообщества разработчиков laravel, оригинальная ссылка: https://learnku.com/laravel/t…

В этой статье мы узнаем, как использовать аутентификацию JWT для создания API restful в laravel. JWT расшифровывается как веб-токены JSON. Мы также будем использовать API для создания полнофункциональных приложений crud для пользовательских продуктов.

При использовании кроссплатформенных приложений API является очень хорошим выбором. В дополнение к веб-сайту, ваш продукт также может иметь приложения для Android и IOS. В этом случае API так же хорош, потому что вы можете писать разные интерфейсы без изменения какого-либо внутреннего кода. При использовании API просто нажмите get, post или другие типы запросов с некоторыми параметрами, и сервер вернет некоторые данные в формате JSON (обозначение объектов JavaScript), который обрабатывается клиентским приложением.

объяснять

Давайте сначала запишем детали и функции вашего приложения. Мы будем использовать аутентификацию JWT для создания базового списка пользовательских продуктов в laravel с использованием restful API.

A Пользователь Будут использоваться следующие функции

  • Зарегистрируйтесь и создайте новую учетную запись
  • Войдите в их учетную запись
  • Выйдите из системы, откажитесь от токена и покиньте приложение
  • Получить данные пользователя для входа
  • Получение списка продуктов, доступных пользователям
  • Найдите конкретные товары по идентификатору
  • Добавьте новый продукт в список пользовательских продуктов
  • Отредактируйте существующие сведения о продукте
  • Удалите существующий продукт из списка пользователей

A Пользователь Требуется

  • имя
  • электронная почта
  • пароль

A Продукт Требуется

  • имя
  • цена
  • количество

Создайте новый проект

Выполнив следующую команду, мы можем запустить и создать новый проект laravel.

composer create-project --prefer-dist laravel/laravel jwt

Это будет указано в имени jwt Создайте новый проект laravel в каталоге.

Настройка пакета расширения JWT

Мы будем использовать пакет расширения tymondesigns/JWT auth, чтобы разрешить нам использовать JWT в laravel.

Установите пакет расширения tymon/JWT auth

Давайте установим этот пакет расширения в приложение laravel. Если вы используете Laravel 5.5 или выше , пожалуйста, выполните следующую команду, чтобы получить dev-разработку Версию пакета JWT:

composer require tymon/jwt-auth:dev-develop --prefer-source

Если вы используете Laravel 5.4 или ниже Чтобы выполнить следующую команду:

composer require tymon/jwt-auth

Для версии laravel Менее 5,5 Вам также необходимо использовать config/app. php Указать поставщика услуг и псевдоним в файле.

'providers' => [
    ....
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
    ....
],
'aliases' => [
    ....
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
    ....
],

Если ваша версия laravel 5.5 или выше , laravel выполнит “автоматическое обнаружение пакетов”.

Опубликовать профиль

о 5.5 или выше Используйте следующую команду для публикации файла конфигурации:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

Для предыдущих Предыдущих версий laravel Следует выполнить следующую команду:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

Приведенная выше команда генерирует config/jwt.php Файл конфигурации. Удалите раздел комментариев, и файл конфигурации будет выглядеть следующим образом:

 env('JWT_SECRET'),

    'keys' => [

        'public' => env('JWT_PUBLIC_KEY'),

        'private' => env('JWT_PRIVATE_KEY'),

        'passphrase' => env('JWT_PASSPHRASE'),
    ],

    'ttl' => env('JWT_TTL', 60),

    'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),

    'algo' => env('JWT_ALGO', 'HS256'),

    'required_claims' => [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti',
    ],

    'persistent_claims' => [
        // 'foo',
        // 'bar',
    ],

    'lock_subject' => true,

    'leeway' => env('JWT_LEEWAY', 0),

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),

    'decrypt_cookies' => false,

    'providers' => [
        'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,

        'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

        'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
    ],
];

Сгенерировать ключ JWT

Токен JWT выдается с зашифрованным ключом. о Laravel 5.5 или выше Выполните следующую команду, чтобы сгенерировать ключ для выдачи токена.

php artisan jwt:secret

Версия Laravel ниже, чем 5.5 Тогда беги:

php artisan jwt:generate

В этом руководстве используется Laravel 5.6 . Следующие шаги в этом руководстве доступны только в 5.5 и 5.6 Проверено в. Может не работать с laravel 5.4 или ниже. Вы можете прочитать документацию для более старых версий laravel.

Промежуточное программное обеспечение для Регистрации

Пакет расширения аутентификации JWT поставляется с промежуточным программным обеспечением, которое нам разрешено использовать. останься app/Http/Kernel.php Зарегистрирован в auth.jwt Промежуточное программное обеспечение:

protected $routeMiddleware = [
    ....
    'auth.jwt' => \Tymon\JWTAuth\Http\Middleware\Authenticate::class,
];

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

Установить маршрут

Прежде чем мы начнем, мы настроим маршрутизацию для всех пунктов, обсуждаемых в этом руководстве. открыть routes/api.php И скопируйте следующий маршрут в свой файл.

Route::post('login', '[email protected]');
Route::post('register', '[email protected]');

Route::group(['middleware' => 'auth.jwt'], function () {
    Route::get('logout', '[email protected]');

    Route::get('user', '[email protected]');

    Route::get('products', '[email protected]');
    Route::get('products/{id}', '[email protected]');
    Route::post('products', '[email protected]');
    Route::put('products/{id}', '[email protected]');
    Route::delete('products/{id}', '[email protected]');
});

Обновить модель пользователя

JWT необходимо реализовать в пользовательской модели TymonJWTAuthContractsJWTSubject Интерфейс. Этот интерфейс должен реализовать два метода getJWTIdentifier И получить пользовательские утверждения JWT . Обновление с app/User.php

getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Логика аутентификации JWT

Давайте напишем логику restful API в laravel с использованием аутентификации JWT.

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

php artisan make:request RegisterAuthRequest

Это будет в приложении/Http/Запросах Создать в каталоге RegisterAuthRequest.php Документы. Вставьте в файл следующий код.

 'required|string',
            'email' => 'required|email|unique:users',
            'password' => 'required|string|min:6|max:10'
        ];
    }
}

Выполните следующую команду, чтобы создать новый ApiController :

php artisan make:controller ApiController

Это будет в app/Http/Контроллеры Создать в каталоге ApiController.php Документы. Вставьте в файл следующий код.

name = $request->name;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);
        $user->save();

        if ($this->loginAfterSignUp) {
            return $this->login($request);
        }

        return response()->json([
            'success' => true,
            'data' => $user
        ], 200);
    }

    public function login(Request $request)
    {
        $input = $request->only('email', 'password');
        $jwt_token = null;

        if (!$jwt_token = JWTAuth::attempt($input)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid Email or Password',
            ], 401);
        }

        return response()->json([
            'success' => true,
            'token' => $jwt_token,
        ]);
    }

    public function logout(Request $request)
    {
        $this->validate($request, [
            'token' => 'required'
        ]);

        try {
            JWTAuth::invalidate($request->token);

            return response()->json([
                'success' => true,
                'message' => 'User logged out successfully'
            ]);
        } catch (JWTException $exception) {
            return response()->json([
                'success' => false,
                'message' => 'Sorry, the user cannot be logged out'
            ], 500);
        }
    }

    public function getAuthUser(Request $request)
    {
        $this->validate($request, [
            'token' => 'required'
        ]);

        $user = JWTAuth::authenticate($request->token);

        return response()->json(['user' => $user]);
    }
}

Позвольте мне объяснить, что произошло с приведенным выше кодом.

оставайтесь зарегистрируйтесь Метод, мы получаем Запрос на регистрацию . Создайте пользователя, используя данные в запросе. Если вход в систему После регистрации Свойство верно После регистрации выберите логин Способ входа для пользователя. В противном случае успешный ответ возвращается вместе с пользовательскими данными.

оставайтесь логин Метод, мы получаем подмножество запроса, которое содержит только адрес электронной почты и пароль. Вызывается со значением, введенным в качестве параметра JWTAuth::попытка() Ответ сохраняется в переменной. Если попытка Метод, возвращается ответ об ошибке. В противном случае будет возвращен успешный ответ.

оставайтесь выход Метод проверки того, содержит ли запрос проверку токена. Вызов метода invalidate делает токен недействительным и возвращает успешный ответ. Если вы зафиксируете Исключение Jetexception Исключение, будет возвращен неудачный ответ.

оставайтесь getAuthUser Метод, чтобы убедиться, что запрос содержит поле токена. Затем вызовите метод authenticate , который возвращает аутентифицированного пользователя. Наконец, возвращается ответ с пользователем.

Раздел аутентификации теперь завершен.

Раздел “Сборка продукта”

Чтобы создать раздел продукта, нам нужно Продукт Модель, контроллер и файл миграции. Выполните следующую команду, чтобы создать Продукт Модель, контроллер и файл миграции.

php artisan make:model Product -mc

Это будет в база данных/миграции Создайте новый файл миграции базы данных в каталоге create_products_table.php , изменить вверх метод.

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id');
        $table->string('name');
        $table->integer('price');
        $table->integer('quantity');
        $table->timestamps();

        $table->foreign('user_id')
            ->references('id')
            ->on('users')
            ->onDelete('cascade');
    });
}

к Продукту Добавить в модель заполняемую Собственность. оставайтесь приложение Открыто в каталоге Product.php Файл и добавьте свойства.

protected $fillable = [
    'name', 'price', 'quantity'
];

Теперь в .env Установите учетные данные базы данных в файле и перенесите базу данных, выполнив следующую команду.

php artisan migrate

Теперь мы должны быть в Пользователь Добавить связь к модели, чтобы получить связанные продукты. останься app/User.php Добавьте следующий метод в.

public function products()
{
    return $this->hasMany(Product::class);
}

оставайтесь приложение/Http/Контроллеры Открыто в каталоге ProductController.php Документы. Добавьте директиву use в начале файла, чтобы переопределить предыдущую.

use App\Product;
use Illuminate\Http\Request;
use JWTAuth;

Теперь мы собираемся реализовать пять подходов.

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

Добавьте конструктор для получения аутентифицированного пользователя и сохраните его в свойстве user .

protected $user;

public function __construct()
{
    $this->user = JWTAuth::parseToken()->authenticate();
}

токен синтаксического анализа Токен из запроса будет разрешен, аутентификация Пользователь аутентифицируется с помощью токена.

Давайте добавим индекс метод.

public function index()
{
    return $this->user
        ->products()
        ->get(['name', 'price', 'quantity'])
        ->toArray();
}

Приведенный выше код очень прост, мы просто используем красноречивый метод, чтобы получить все продукты, а затем сформировать массив результатов. Наконец, мы возвращаем массив. Laravel автоматически преобразует его в JSON и создаст код ответа на 200 успешных запросов.

Продолжайте реализовывать показывать метод.

public function show($id)
{
    $product = $this->user->products()->find($id);

    if (!$product) {
        return response()->json([
            'success' => false,
            'message' => 'Sorry, product with id ' . $id . ' cannot be found'
        ], 400);
    }

    return $product;
}

Это также очень легко понять. Нам просто нужно найти товар по идентификатору. Если продукт не существует, возвращается ответ на ошибку 400. В противном случае возвращается массив продуктов.

Далее следует хранить метод

public function store(Request $request)
{
    $this->validate($request, [
        'name' => 'required',
        'price' => 'required|integer',
        'quantity' => 'required|integer'
    ]);

    $product = new Product();
    $product->name = $request->name;
    $product->price = $request->price;
    $product->quantity = $request->quantity;

    if ($this->user->products()->save($product))
        return response()->json([
            'success' => true,
            'product' => $product
        ]);
    else
        return response()->json([
            'success' => false,
            'message' => 'Sorry, product could not be added'
        ], 500);
}

оставайтесь храните Метод, чтобы убедиться, что запрос содержит название, цену и количество. Затем используйте данные в запросе для создания новой модели продукта. Если продукт успешно записан в базу данных, будет возвращен ответ “успешно”, в противном случае будет возвращен пользовательский ответ на 500 ошибок.

реализация обновление метод

public function update(Request $request, $id)
{
    $product = $this->user->products()->find($id);

    if (!$product) {
        return response()->json([
            'success' => false,
            'message' => 'Sorry, product with id ' . $id . ' cannot be found'
        ], 400);
    }

    $updated = $product->fill($request->all())
        ->save();

    if ($updated) {
        return response()->json([
            'success' => true
        ]);
    } else {
        return response()->json([
            'success' => false,
            'message' => 'Sorry, product could not be updated'
        ], 500);
    }
}

оставайтесь обновите Метод, мы получаем продукт по идентификатору. Если продукт не существует, возвращается ответ 400. Затем мы используем данные в методе запроса заполнения для заполнения сведений о продукте. Обновите модель продукта и сохраните ее в базе данных. Если запись успешно обновлена, возвращается ответ 200 “Успешно”. В противном случае клиенту будет возвращен ответ на 500 внутренних ошибок сервера.

Теперь давайте сделаем это уничтожим методом.

public function destroy($id)
{
    $product = $this->user->products()->find($id);

    if (!$product) {
        return response()->json([
            'success' => false,
            'message' => 'Sorry, product with id ' . $id . ' cannot be found'
        ], 400);
    }

    if ($product->delete()) {
        return response()->json([
            'success' => true
        ]);
    } else {
        return response()->json([
            'success' => false,
            'message' => 'Product could not be deleted'
        ], 500);
    }
}

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

Код контроллера теперь завершен, и полный код контроллера находится здесь.

тест

Давайте сначала проверим аутентификацию. Мы будем использовать команду serve для запуска веб-службы на разработчике, или вместо этого вы можете использовать виртуальный хост. Выполните следующую команду, чтобы запустить веб-службу.

php artisan serve

Он будет слушать localhost:8000

Для тестирования restful API мы используем postman. После заполнения формы запроса давайте запросим ее зарегистрироваться маршрут.

Отправьте запрос, и вы получите токен.

Наши пользователи теперь зарегистрированы и прошли проверку подлинности. Мы можем отправить еще один запрос на обнаружение входа Маршрута, результат вернет 200 и токен.

Получить сведения о пользователе

Проверка подлинности завершена. Затем протестируйте раздел продукта, сначала создав продукт.

Теперь по запросу индекс Методы получения продукта.

Вы можете протестировать другие маршруты, и все они будут работать.

Исходный код учебника на GitHub.