Эта статья переслана из профессионального сообщества разработчиков 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.