laravel-12/SANCTUM_SETUP_GUIDE.md

16 KiB
Raw Blame History

Руководство по установке и настройке Laravel Sanctum с API авторизацией

Описание

Данное руководство описывает процесс установки и настройки Laravel Sanctum для API аутентификации с использованием wadakatu/laravel-spectrum для автоматической генерации Swagger документации.


Содержание

  1. Установка пакетов
  2. Настройка Sanctum
  3. Структура API
  4. API Endpoints
  5. Использование API
  6. Swagger документация
  7. Команды Artisan

1. Установка пакетов

1.1 Установка Laravel Sanctum

composer require laravel/sanctum

1.2 Установка wadakatu/laravel-spectrum

composer require wadakatu/laravel-spectrum

1.3 Публикация конфигураций

# Публикация Sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

# Публикация Spectrum (если требуется)
php artisan vendor:publish --provider="Wadakatu\LaravelSpectrum\LaravelSpectrumServiceProvider"

1.4 Запуск миграций

php artisan migrate

Примечание: Если таблица personal_access_tokens уже существует, пропустите этот шаг.


2. Настройка Sanctum

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

Добавьте трейт HasApiTokens в модель User:

// app/Models/User.php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    // ...
}

2.2 Настройка middleware

Обновите файл bootstrap/app.php:

// bootstrap/app.php

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        //
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })->create();

Важно: Не используйте statefulApi() для чистого token-based API, это вызовет ошибку 419 CSRF.

2.3 Конфигурация Sanctum

// config/sanctum.php

return [
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
    ))),

    'guard' => ['web'],

    'expiration' => null,

    'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),

    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
];

3. Структура API

3.1 Директории

app/
├── Http/
│   ├── Controllers/
│   │   └── Api/
│   │       ├── AuthController.php
│   │       └── PostController.php
│   ├── Requests/
│   │   ├── LoginRequest.php
│   │   ├── RegisterRequest.php
│   │   ├── StorePostRequest.php
│   │   └── UpdatePostRequest.php
│   └── Resources/
│       ├── PostCollection.php
│       ├── PostResource.php
│       └── UserResource.php
└── Policies/
    └── PostPolicy.php

3.2 API Resources

Laravel Spectrum автоматически определяет структуру ответа из API Resources.

// app/Http/Resources/UserResource.php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'role' => $this->role,
            'created_at' => $this->created_at,
        ];
    }
}
// app/Http/Resources/PostResource.php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'user_id' => $this->user_id,
            'user' => new UserResource($this->whenLoaded('user')),
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

3.3 Form Requests

Laravel Spectrum автоматически определяет правила валидации из Form Requests.

// app/Http/Requests/RegisterRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class RegisterRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ];
    }
}
// app/Http/Requests/LoginRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LoginRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'email' => ['required', 'string', 'email'],
            'password' => ['required', 'string'],
        ];
    }
}
// app/Http/Requests/StorePostRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
        ];
    }
}

4. API Endpoints

4.1 Маршруты

// routes/api.php

use App\Http\Controllers\Api\AuthController;
use App\Http\Controllers\Api\PostController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
*/

// Swagger Documentation - редирект на Swagger UI
Route::get('/docs', function () {
    return redirect()->to('/spectrum/openapi.html');
});

// Public routes (без авторизации)
Route::post('/register', [AuthController::class, 'register'])->name('api.register');
Route::post('/login', [AuthController::class, 'login'])->name('api.login');

// Protected routes (требуют авторизации)
Route::middleware('auth:sanctum')->group(function () {
    // Auth
    Route::post('/logout', [AuthController::class, 'logout'])->name('api.logout');
    Route::get('/user', [AuthController::class, 'user'])->name('api.user');

    // Posts
    Route::get('/posts', [PostController::class, 'index'])->name('api.posts.index');
    Route::post('/posts', [PostController::class, 'store'])->name('api.posts.store');
    Route::get('/posts/{post}', [PostController::class, 'show'])->name('api.posts.show');
    Route::put('/posts/{post}', [PostController::class, 'update'])->name('api.posts.update');
    Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('api.posts.destroy');
});

4.2 Список Endpoints

Метод Endpoint Описание Авторизация
POST /api/register Регистрация Нет
POST /api/login Вход Нет
POST /api/logout Выход Да
GET /api/user Текущий пользователь Да
GET /api/posts Список постов Да
POST /api/posts Создание поста Да
GET /api/posts/{id} Просмотр поста Да
PUT /api/posts/{id} Обновление поста Да
DELETE /api/posts/{id} Удаление поста Да
GET /api/docs OpenAPI спецификация Нет

5. Использование API

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

curl -X POST http://la.test/api/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "password": "password123",
    "password_confirmation": "password123"
  }'

5.2 Вход

curl -X POST http://la.test/api/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "password123"
  }'

5.3 Создание поста

curl -X POST http://la.test/api/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {token}" \
  -d '{
    "title": "My First Post",
    "content": "This is the content of my post."
  }'

5.4 Выход

curl -X POST http://la.test/api/logout \
  -H "Authorization: Bearer {token}"

6. Swagger документация

6.1 Доступ к документации

Документация Swagger UI доступна по адресу:

{APP_URL}/api/docs

Например: http://la.test/api/docs

6.2 Генерация документации

Laravel Spectrum генерирует готовый HTML с Swagger UI:

php artisan spectrum:generate --format=html

Это создаёт файл public/spectrum/openapi.html.

6.3 Настройка доступа

При генерации с флагом --format=html symlink создаётся автоматически.

Если symlink отсутствует, создайте его вручную:

ln -sf /home/user/www/lara/storage/app/spectrum /home/user/www/lara/public/spectrum

6.4 Файлы документации

public/
└── spectrum/
    ├── openapi.html        # Swagger UI (генерируется с --format=html)
    └── openapi.json        # OpenAPI спецификация

6.5 Маршрут для документации

// routes/api.php

// Swagger Documentation
Route::get('/docs', function () {
    return redirect()->to('/spectrum/openapi.html');
});

7. Команды Laravel Spectrum

7.1 Основные команды

Laravel Spectrum поставляется с готовыми командами для работы с документацией.

Команда Описание
php artisan spectrum:generate Генерация OpenAPI документации
php artisan spectrum:watch Режим реального времени (port 8080)
php artisan spectrum:mock Запуск mock сервера (port 8081)
php artisan spectrum:cache clear Очистка кэша анализа

7.2 Генерация документации

# Генерация документации в формате HTML
php artisan spectrum:generate --format=html

Вывод:

🚀 Generating API documentation...
🔍 Analyzing routes...
Found 9 API routes
📝 Generating OpenAPI specification...
✅ Documentation generated: /home/user/www/lara/public/spectrum/openapi.html
⏱️  Generation completed in 0.17 seconds
💾 Cache: 5 files, 7.04 KB
✅ Documentation generated successfully!

7.3 Режим реального времени

# Запуск режима watch
php artisan spectrum:watch
  • Запускает локальный сервер на http://localhost:8080
  • Автоматически обнаруживает изменения в файлах
  • Обновляет документацию в реальном времени

7.4 Mock сервер

# Запуск mock API сервера
php artisan spectrum:mock
  • Запускает mock сервер на http://localhost:8081
  • Генерирует моковые данные на основе спецификации
  • Позволяет тестировать API без реального бэкенда

7.5 Обновление документации

После добавления новых endpointов:

# Очистить кэш и перегенерировать
php artisan spectrum:cache clear
php artisan spectrum:generate

8. Политики доступа

8.1 PostPolicy

// app/Policies/PostPolicy.php

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
}

8.2 Регистрация политики

Политики автоматически обнаруживаются Laravel. Для ручной регистрации:

// app/Providers/AuthServiceProvider.php

namespace App\Providers;

use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        Post::class => PostPolicy::class,
    ];

    public function boot(): void
    {
        $this->registerPolicies();
    }
}

9. Конфигурация .env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:...
APP_URL=http://la.test

DB_CONNECTION=sqlite

SESSION_DRIVER=database

10. Тестирование

# Проверка списка маршрутов
php artisan route:list --path=api

# Генерация документации
php artisan spectrum:generate

# Запуск сервера
php artisan serve

Troubleshooting

Проблема: 401 Unauthorized

Решение:

  1. Проверьте токен в заголовке Authorization: Bearer {token}
  2. Убедитесь, что используете префикс Bearer

Проблема: 419 CSRF Error

Решение: Уберите statefulApi() из middleware в bootstrap/app.php:

->withMiddleware(function (Middleware $middleware): void {
    // Не используйте statefulApi() для token-based API
})

Проблема: Rate limiter not defined

Решение: Не используйте throttleApi():

// Неправильно
$middleware->throttleApi();

// Правильно (оставить пустым или удалить)
$middleware->api();

Заключение

Теперь у вас есть полностью настроенный API с:

  • Laravel Sanctum - аутентификация через токены
  • wadakatu/laravel-spectrum - автоматическая генерация Swagger документации
  • API Resources - форматирование ответов
  • Form Requests - валидация
  • Swagger документация - /api/docs

Команды для работы:

php artisan spectrum:generate  # Генерация документации
php artisan spectrum:watch     # Режим разработки
php artisan spectrum:mock     # Mock сервер

Документация: http://la.test/api/docs