17 KiB
Руководство по установке и настройке Laravel Sanctum с API авторизацией
Описание
Данное руководство описывает процесс установки и настройки Laravel Sanctum для API аутентификации с использованием wadakatu/laravel-spectrum для автоматической генерации Swagger документации.
Содержание
- Установка пакетов
- Настройка Sanctum
- Структура API
- API Endpoints
- Использование API
- Swagger документация
- Команды 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('/docs/index.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 Генерация документации
Сначала сгенерируйте OpenAPI спецификацию:
php artisan spectrum:generate
6.3 Настройка доступа
Для работы Swagger UI необходимо:
1. Создать символическую ссылку:
ln -sf /home/user/www/lara/storage/app/spectrum /home/user/www/lara/public/spectrum
2. Создать HTML файл Swagger UI:
<!-- public/docs/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Documentation - Swagger UI</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js"></script>
<script>
window.onload = function() {
SwaggerUIBundle({
url: "/spectrum/openapi.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis
],
docExpansion: "list",
persistAuthorization: true
});
};
</script>
</body>
</html>
6.4 Файлы документации
public/
└── docs/
└── index.html # Swagger UI
storage/
└── app/
└── spectrum/
└── openapi.json # OpenAPI спецификация
6.5 Маршрут для документации
// routes/api.php
// Swagger Documentation
Route::get('/docs', function () {
return redirect()->to('/docs/index.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 Генерация документации
# Генерация документации
php artisan spectrum:generate
Вывод:
🚀 Generating API documentation...
🔍 Analyzing routes...
Found 9 API routes
📝 Generating OpenAPI specification...
✅ Documentation generated: /home/user/www/lara/storage/app/spectrum/openapi.json
⏱️ 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
Решение:
- Проверьте токен в заголовке
Authorization: Bearer {token} - Убедитесь, что используете префикс
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