Когда тебе не нужен цирк с OAuth2 и танцы с рефреш-токенами, приходит Sanctum. Он проще, чем Passport, и его реально можно прикрутить за вечер. Но Laravel, как обычно, умалчивает, что у этого "простого решения" тоже хватает тараканов.

Установка: та же песня

composer create-project laravel/laravel sanctum-example
cd sanctum-example
composer require laravel/sanctum
php artisan migrate
php artisan sanctum:install

Всё, у тебя уже есть токены в базе и конфиг sanctum.php. Для Laravel это почти рекорд по простоте.

User-модель: допинг для токенов

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Да, снова трейт. Laravel любит трейты и без него токены работать не будут.

Маршруты: регистрация, логин, "кто я?"

В routes/api.php:

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

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
});

И всё, у тебя есть API-эндпоинты, которые требуют токен.

Контроллеры: без соплей

Регистрация:

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

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

        return response()->json(['message' => 'User registered successfully']);
    }
}

Логин:

class LoginController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (!Auth::attempt($credentials)) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        $token = Auth::user()->createToken('MyApp')->plainTextToken;

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

Разница с Passport в том, что тут всё проще: без refresh-токенов и без лишних сущностей. Тебе просто выдают plainTextToken и сказали "живи".

Тесты: Postman, Insomnia, curl в зубы

Регистрируешь юзера, логинишься, получаешь токен. Дальше кидаешь его в заголовок Authorization: Bearer ... и стучишься в /user. Если видишь свои данные — значит жив.

Где Sanctum реально тащит

  • Если у тебя SPA или мобильное приложение, и надо просто выдать токен и проверять его.
  • Если не хочется городить OAuth2 и читать RFC, от которых мозг вскипает.
  • Если важна простота — Sanctum не перегружает код.

Где он подставляет

  • Нет нормальной поддержки refresh-токенов из коробки. Хочешь обновление токена — думай сам.
  • Токены в базе хранятся в открытую (plain text не хранится, но хэш да, и это всё равно может быть точкой уязвимости, если не следить).
  • Если у тебя распределённая система, придётся шаманить с синхронизацией токенов. Sanctum для простых приложений, не для микросервисного зоопарка.

Вывод

Sanctum — это "токены на минималках". Для мелких и средних проектов хватает за глаза. Простая аутентификация без костылей OAuth2. Но если у тебя продукт уровня банка, где всё крутится на безопасности и долгоживущих токенах, забудь — бери что-то серьёзнее.