Как реализовать JWT-аутентификацию в Laravel 12

В этом материале подробно разобрана настройка JWT аутентификации в Laravel 12. Мы пройдем весь путь от установки пакета до полностью рабочего контроллера, middleware и маршрутов. Все примеры можно использовать сразу в проекте.


Что такое JWT и зачем он нужен

JWT (JSON Web Token) - это компактный токен, который содержит информацию о пользователе и подписывается секретным ключом. Сервер не хранит сессии, а просто проверяет токен в каждом запросе.

JWT обычно используют в приложениях которые использую API. Это могут быть SPA или мобильные приложения.


Установка JWT пакета

Для Laravel самый популярный пакет который пердоставляет jwt auth это tymon/jwt-auth.

Чтобы его установить выполним следующую комманду:

composer require tymon/jwt-auth

Затем нужно опубликовать конфигурацию пакета:

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

После этого появится файл:

config/jwt.php

Генерация JWT секретного ключа

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

php artisan jwt:secret

После чего, в файле .env появится строка:

JWT_SECRET=some_long_random_string

Без этого ключа JWT работать не будет.


Настройка guards в auth.php

Откройте файл:

config/auth.php

Найдите раздел guards и настройте API guard так:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Теперь Laravel будет использовать JWT для API аутентификации.


Обновление модели User

Откройте модель пользователя:

app/Models/User.php

Добавьте интерфейс JWTSubject и необходимые методы. Ниже полная модель с уже добавленными методами:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
    ];

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }
}

Здесь:

  • getJWTIdentifier возвращает ID пользователя

  • getJWTCustomClaims позволяет добавить свои данные в токен


Создание AuthController

Создаем контроллер с реализацие auth:

php artisan make:controller AuthController

И приводим его к виду как в коде ниже:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = JWTAuth::fromUser($user);

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

    public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        if (!$token = auth('api')->attempt($credentials)) {
            return response()->json([
                'error' => 'Неверный email или пароль',
            ], 401);
        }

        return response()->json([
            'token' => $token,
            'user' => auth('api')->user(),
        ]);
    }

    public function me()
    {
        return response()->json(auth('api')->user());
    }

    public function update(Request $request)
    {
        $user = auth('api')->user();

        $request->validate([
            'name' => 'sometimes|string|max:255',
            'password' => 'sometimes|min:6',
        ]);

        if ($request->name) {
            $user->name = $request->name;
        }

        if ($request->password) {
            $user->password = Hash::make($request->password);
        }

        $user->save();

        return response()->json($user);
    }

    public function logout()
    {
        auth('api')->logout();

        return response()->json([
            'message' => 'Вы успешно вышли',
        ]);
    }
}

Что здесь происходит:

  • register создает пользователя и сразу выдает JWT токен

  • login проверяет данные и возвращает токен

  • me возвращает текущего пользователя

  • update обновляет профиль

  • logout инвалидирует токен


Middleware для защиты маршрутов

Создаем middleware чтобы предотвратить неавторизованный доступ к маршрутам:

php artisan make:middleware JwtMiddleware

И сам код middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Exception;
use Tymon\JWTAuth\Facades\JWTAuth;

class JwtMiddleware
{
    public function handle($request, Closure $next)
    {
        try {
            JWTAuth::parseToken()->authenticate();
        } catch (Exception $e) {
            return response()->json([
                'error' => 'Неавторизован',
            ], 401);
        }

        return $next($request);
    }
}

Регистрация middleware в Laravel 12

В Laravel 12 middleware регистрируются в bootstrap/app.php. Откройте файл и добавьте следующее:

->withMiddleware(function ($middleware) {
    $middleware->alias([
        'jwt' => \App\Http\Middleware\JwtMiddleware::class,
    ]);
})

API маршруты

Откройте файл:

routes/api.php

и добавьте маршруты:

use App\Http\Controllers\AuthController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);

Route::middleware('jwt')->group(function () {
    Route::get('/me', [AuthController::class, 'me']);
    Route::put('/me', [AuthController::class, 'update']);
    Route::post('/logout', [AuthController::class, 'logout']);
});

Как передавать токен

В каждом защищенном запросе передавайте заголовок с токеном JWT(без заголовка middleware вернет ошибку 401):

Authorization: Bearer YOUR_JWT_TOKEN

В результате у вас получится полноценная система аутентификации с JWT, которая подходит для SPA и мобильных приложений, а также REST-API на Laravel 12.

Комментарии (0)

Войдите, чтобы оставить комментарий

Похожие статьи

Как использовать docker exec для запуска команд в контейнере Docker

Использование команды docker exec для запуска команд внутри работающего Docker-контейнера. Приведены примеры команд, вывод консоли, разбор опций и рекомендации по устранению ошибок.

12 0 1 мин

Настройка SSH аутентификации на Linux

Подробное руководство по настройке аутентификации по SSH-ключам на Linux-сервере. В статье разобраны генерация ключей, копирование на сервер, проверка подключения и отключение входа по паролю с примерами консольных команд.

13 0 1 мин