Laravel API с Sanctum
Laravel API с Sanctum
Первая программа на Laravel строит классический сайт: формы, Blade, сессия в cookie. Современные проекты часто отдают JSON отдельному клиенту — SPA на Vue/React, мобильное приложение, другой сервис.
API (Application Programming Interface) здесь — набор URL, которые принимают и возвращают JSON вместо HTML.
Laravel Sanctum выдаёт пользователю API-токен — длинную строку, которую клиент передаёт в заголовке Authorization: Bearer … при каждом запросе. Это проще полноценного OAuth2 для «своего» фронта и мобильных приложений.
Обзор MVC: Laravel 143.md. Альтернатива в Symfony: 144.md.
Web и API — в чём разница
routes/web.php | routes/api.php | |
|---|---|---|
| Ответ | HTML (Blade) | JSON |
| Сессия | Cookie, CSRF-токен в формах | Обычно без cookie-сессии |
| Префикс URL | / | /api/… (Laravel добавляет автоматически) |
| Middleware | web (CSRF, сессия) | api (throttle, без CSRF для токена) |
Ошибка 419 Page Expired при POST в API чаще всего значит, что запрос попал в web.php и Laravel ждёт CSRF-токен. API-маршруты держите в api.php.
Термины
| Термин | Значение |
|---|---|
| JSON | Текстовый формат { "key": "value" } для обмена данными |
| Bearer token | Токен в заголовке Authorization: Bearer abc123… |
| Resource | Класс, который задаёт, какие поля модели уходят в JSON |
| Sanctum | Пакет Laravel для токенов и SPA-аутентификации |
| 401 Unauthorized | «Не знаю, кто ты» — нет или неверный токен |
| 403 Forbidden | «Знаю, но нельзя» — Policy запретила действие |
Что получится в конце
| Шаг | Результат |
|---|---|
GET /api/notes без токена | 401 |
POST /api/login с email и password | JSON { "token": "…" } |
Запросы с Authorization: Bearer … | CRUD заметок |
Модель Note
После учебного проекта из 1431:
php artisan make:model Note -m
app/Models/Note.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
protected $fillable = ['text'];
}
В миграции — поле text (string). Затем:
php artisan migrate
$fillable разрешает массовое заполнение Note::create(['text' => '…']) — без этого Laravel проигнорирует поле из соображений безопасности.
Установка Sanctum
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Миграция создаёт таблицу personal_access_tokens — там хранятся хэши токенов.
app/Models/User.php:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Трейт HasApiTokens добавляет метод $user->createToken('имя')->plainTextToken.
В Laravel 11+ маршруты API часто уже защищены middleware auth:sanctum в группе в routes/api.php.
API Resource — форма JSON
Модель Note в БД может иметь десятки полей. В API клиенту отдают только нужные — через Resource:
php artisan make:resource NoteResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class NoteResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'text' => $this->text,
'created_at' => $this->created_at?->toIso8601String(),
];
}
}
$this внутри Resource — обёртка над моделью Note. ?-> — безопасный вызов, если дата null.
NoteResource::collection($notes) превращает коллекцию в JSON-массив объектов одинаковой структуры.
Контроллер API
php artisan make:controller Api/NoteController --api
Флаг --api создаёт методы без create/edit для HTML-форм.
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\NoteResource;
use App\Models\Note;
use Illuminate\Http\Request;
class NoteController extends Controller
{
public function index()
{
return NoteResource::collection(Note::latest()->get());
}
public function store(Request $request)
{
$data = $request->validate(['text' => 'required|string|max:2000']);
$note = Note::create($data);
return new NoteResource($note);
}
public function destroy(Note $note)
{
$note->delete();
return response()->noContent();
}
}
validate при ошибке вернёт JSON 422 с описанием полей. noContent() — ответ 204 без тела (стандарт для DELETE).
Маршруты и логин
routes/api.php:
use App\Http\Controllers\Api\NoteController;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route;
Route::post('/login', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$token = $user->createToken('api')->plainTextToken;
return response()->json(['token' => $token]);
});
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('notes', NoteController::class)->only(['index', 'store', 'destroy']);
});
Разбор логина
validate— email и password обязательны.User::where('email', …)->first()— ищем пользователя.Hash::check($plain, $user->password)— сравнение с хэшем в БД (пароль в открытом виде в БД не хранится).createToken('api')— новая запись вpersonal_access_tokens;plainTextTokenпоказывается один раз клиенту.
Защищённая группа: middleware auth:sanctum читает Bearer-токен и подставляет $request->user().
Создайте пользователя: php artisan tinker → User::factory()->create(['email' => 'user@example.com', 'password' => bcrypt('password')]).
Проверка через curl
curl -X POST http://127.0.0.1:8000/api/login \
-H "Content-Type: application/json" \
-d "{\"email\":\"user@example.com\",\"password\":\"password\"}"
Ответ: {"token":"1|abcdef…"}. Скопируйте значение token.
curl http://127.0.0.1:8000/api/notes \
-H "Authorization: Bearer 1|abcdef..."
curl -X POST http://127.0.0.1:8000/api/notes \
-H "Authorization: Bearer 1|abcdef..." \
-H "Content-Type: application/json" \
-d "{\"text\":\"Заметка из API\"}"
Префикс /api Laravel добавляет к маршрутам из routes/api.php автоматически.
Частые ошибки
| Симптом | Причина |
|---|---|
| 419 / CSRF | POST на web.php вместо api.php |
| 401 на все запросы | Нет заголовка Authorization: Bearer или опечатка в токене |
| Пустой JSON | Забыли обернуть в NoteResource |
| 422 на store | Не передали text или превышен max:2000 |
Что попробовать дальше
- Feature-тест:
$this->actingAs($user)->getJson('/api/notes')илиwithToken()— PHPUnit. - Policy: удалять заметку может только автор — Очереди и политики.
- SPA на Vue — хранить токен в
localStorageи передавать вfetch.
Связанные материалы
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). PHP как язык веб-разработки - роль серверного исполнения, базовый синтаксис и место в современном стеке. Экосистема PHP-приложений - фреймворки, инструменты, пакеты и типовые архитектурные подходы веб-разработки. PHP — это язык программирования общего назначения, который изначально создавался для динамической генерации веб-страниц. Модель исполнения PHP - жизненный цикл запроса, серверный контекст и экосистема популярных CMS. История PHP - эволюция языка от простых скриптов до зрелой платформы серверной веб-разработки. Composer в PHP - управление зависимостями, автозагрузка классов и воспроизводимая сборка проектов. Параметр opcache.fast_shutdown ускоряет завершение работы скрипта за счёт пропуска стандартной процедуры освобождения памяти. Вместо этого используется механизм сборщика мусора операционной системы. Локальная среда разработки на PHP - настройка стека, запуск приложения и отладка без продакшен-сервера. Набор советов, правил, принципов и обычаев в разработке на этом языке. Фреймворки и библиотеки PHP - организация сервисов, вспомогательные компоненты и ускорение разработки веб-приложений. Гайд по установке и настройке с написанием первой программы и её запуском. Примеры простых и полезных консольных приложений с демонстрацией концепций языка.PHP - язык веб-разработки
Экосистема PHP-приложений
Что требуется знать перед началом изучения языка программирования PHP
Модель исполнения PHP
История языка PHP
Composer - управление зависимостями в PHP
Настройка веб-сервера для работы с PHP
Локальная среда разработки на PHP
Рекомендации по разработке на PHP
Фреймворки и библиотеки PHP
Первая программа на PHP
Простые приложения на PHP