Previous slide Next slide Toggle fullscreen Toggle overview view Open presenter view
Разработка веб-приложений с использованием программных платформ
Тема 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
План лекции
Основные вопросы
Аутентификация и стартовые наборы (Starter Kits)
Авторизация доступа: механизмы Gates и Policies
Изоляция валидации: классы Form Request
Создание защищённого RESTful API и Laravel Sanctum
Трансформация вывода: Eloquent API Resources
Файловые хранилища Storage и ссылка storage:link
Стратегии кэширования данных и тегирование
Автоматизированное тестирование на базе Pest
Чеклист подготовки и развёртывания (Deployment)
Цели лекции
Освоить настройку готовой системы входа
Разграничить права доступа пользователей к данным
Вынести валидацию из контроллеров в запросы форм
Спроектировать stateless API со спецификацией JSON
Реализовать безопасную загрузку пользовательских файлов
Снизить нагрузку на СУБД с помощью кэширования
Написать проверяемый Feature-тест для эндпоинта API
Освоить регламент оптимизации для боевых серверов
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
От прототипа к production-системе
Учебный прототип (Лекция 3)
Все действия доступны любому посетителю
Правила валидации записаны прямо в контроллере
Интерфейс жестко привязан к Blade-шаблонам
Загрузка пользовательских файлов не поддерживается
При каждом запросе выполняются прямые запросы к СУБД
Отсутствуют автоматические тесты бизнес-логики
Нет оптимизации конфигураций под нагрузку
Промышленная система (Лекция 4)
Идентификация, аутентификация и верификация
Разграничение прав владения ресурсами (Policies)
Выделенные классы запросов FormRequest
Независимый программный интерфейс RESTful API
Абстракция файловых дисков (локальные и облачные)
Кэширование тяжелых запросов в Redis
Регрессионная защита автотестами на Pest
Чеклист компиляции и безопасный режим .env
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Аутентификация: стартовые наборы
Laravel Breeze
Официальный легковесный стартовый набор
Реализует регистрацию, логин, сброс пароля, email-верификацию
Варианты стека: Blade, Inertia (Vue/React) или API-only
Код полностью доступен в вашем проекте для правок
Идеальный выбор для большинства стандартных систем
Laravel Jetstream
Расширенный каркас для сложных корпоративных систем
Встроенная двухфакторная аутентификация (2FA / TOTP)
Управление командами (teams) и ролевыми приглашениями
Интеграция с Sanctum для выпуска личных API-токенов
Стек на базе Livewire или Inertia + Tailwind CSS
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Установка и генерация Breeze
Команды развёртывания
composer require laravel/breeze --dev
php artisan breeze:install blade
npm install && npm run build
php artisan migrate
Команда breeze:install создаёт структуру «под ключ»
Сгенерированные артефакты
Контроллеры: app/Http/Controllers/Auth/
Шаблоны форм: resources/views/auth/
Маршруты: routes/auth.php
Запросы валидации: app/Http/Requests/Auth/
Таблицы БД: users, password_reset_tokens, sessions
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Защита маршрутов через Middleware
Назначение встроенных middleware
guest — доступ открыт исключительно неавторизованным гостям
auth — доступ разрешен только пользователям с активной сессией
verified — требует подтверждения email перед доступом к экрану
Пример группировки в routes/web.php
Route ::middleware ('guest' )->group (function () {
Route ::get ('/login' , [AuthController ::class , 'create' ])->name ('login' );
Route ::post ('/login' , [AuthController ::class , 'store' ]);
});
Route ::middleware (['auth' , 'verified' ])->group (function () {
Route ::get ('/dashboard' , fn() => view ('dashboard' ))->name ('dashboard' );
Route ::get ('/profile' , [ProfileController ::class , 'edit' ])->name ('profile.edit' );
});
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Аутентификация vs Авторизация
Аутентификация (Authentication)
Вопрос: «Кто вы такой?»
Идентификация субъекта и проверка подлинности пароля
Выполняется на входе в систему (логин, токен)
Фиксирует состояние пользователя в Auth::user()
При ошибке возвращается HTTP-код:
401 Unauthorized
Авторизация (Authorization)
Вопрос: «Имеете ли вы право на это действие?»
Проверка полномочий на изменение конкретного ресурса
Применяется к сущностям: «может ли User #5 удалить Post #12?»
Реализуется через Gates и объектные Policies
При отказе возвращается HTTP-код:
403 Forbidden
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Простые проверки: механизм Gates
Регистрация в AppServiceProvider
namespace App \Providers ;
use App \Models \User ;
use Illuminate \Support \Facades \Gate ;
use Illuminate \Support \ServiceProvider ;
class AppServiceProvider extends ServiceProvider
{
public function boot ( ): void
{
Gate ::define ('access-admin-panel' , function (User $user ) {
return $user ->is_admin === true ;
});
}
}
Проверка в коде приложения
if (Gate ::allows ('access-admin-panel' )) {
}
if (Gate ::denies ('access-admin-panel' )) {
abort (403 );
}
Gate ::authorize ('access-admin-panel' );
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Объектные политики (Policies)
Назначение и создание политики
php artisan make:policy PostPolicy --model=Post
Создаётся файл app/Policies/PostPolicy.php
Методы политики соответствуют типовым действиям:
viewAny, view, create, update, delete
Автоматически связывается с моделью по соглашению имен
Реализация метода проверки
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 || $user ->is_admin;
}
}
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Вызов политик в контроллере и Blade
Проверка в PostController
class PostController extends Controller
{
public function edit (Post $post ): View
{
$this ->authorize ('update' , $post );
return view ('posts.edit' , compact ('post' ));
}
public function destroy (Post $post ): RedirectResponse
{
$this ->authorize ('delete' , $post );
$post ->delete ();
return redirect ()->route ('posts.index' );
}
}
Отображение кнопок в Blade-шаблоне
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}" class="btn-edit">
Редактировать
</a>
@endcan
@can('delete', $post)
<form method="POST" action="{{ route('posts.destroy', $post) }}">
@csrf
@method('DELETE')
<button type="submit">Удалить</button>
</form>
@endcan
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Проблема валидации в контроллерах
«Толстый» контроллер (Антипаттерн)
Метод store разрастается до десятков строк
Правила валидации смешаны с координацией запроса
Дублирование правил при наличии Web и API контроллеров
Невозможность изолированного повторного использования
Затруднено модульное тестирование логики валидации
Создание отдельного класса запроса для каждой формы
Валидация выполняется до попадания управления в контроллер
Встроенная проверка прав авторизации на отправку формы
Контроллер получает исключительно проверенный массив данных
Соблюдение принципа единственной ответственности (SRP)
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Создание класса через Artisan
php artisan make:request StorePostRequest
Создаётся файл app/Http/Requests/StorePostRequest.php
Наследует Illuminate\Foundation\Http\FormRequest
Внедряется в контроллер через внедрение зависимостей
Метод проверки прав authorize()
namespace App \Http \Requests ;
use Illuminate \Foundation \Http \FormRequest ;
class StorePostRequest extends FormRequest
{
public function authorize ( ): bool
{
return $this ->user () !== null ;
}
}
Если вернуть false, Laravel немедленно вернёт HTTP 403 Forbidden
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Правила и локализация ошибок
Метод rules()
public function rules ( ): array
{
return [
'title' => ['required' , 'string' , 'min:5' , 'max:255' ],
'body' => ['required' , 'string' , 'min:20' ],
'category' => ['required' , 'exists:categories,id' ],
];
}
Поддерживаются массивы правил или строковые разделители |
Правило exists проверяет существование записи в БД
Метод кастомных сообщений messages()
public function messages ( ): array
{
return [
'title.required' => 'Укажите заголовок статьи.' ,
'title.min' => 'Заголовок должен быть не короче 5 символов.' ,
'body.required' => 'Текст статьи обязателен к заполнению.' ,
];
}
Позволяет задать дружественные понятные сообщения на русском языке
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Безопасная обработка в контроллере
Очищенный контроллер
namespace App \Http \Controllers ;
use App \Http \Requests \StorePostRequest ;
use App \Models \Post ;
use Illuminate \Http \RedirectResponse ;
class PostController extends Controller
{
public function store (StorePostRequest $request ): RedirectResponse
{
$validated = $request ->validated ();
$validated ['user_id' ] = $request ->user ()->id;
$post = Post ::create ($validated );
return redirect ()->route ('posts.show' , $post )
->with ('status' , 'Статья успешно опубликована!' );
}
}
Гарантии безопасности
$request->validated() защищает от Mass Assignment
Посторонние ключи из формы отбрасываются
При ошибке валидации метод контроллера даже не начинает выполняться:
Для браузера: редирект назад с ошибками
Для API: ответ HTTP 422 с JSON-ошибками
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Архитектура RESTful API
Базовые принципы REST
Stateless : сервер не хранит сессионное состояние между запросами
Клиент передаёт токен авторизации в каждом HTTP-запросе
Вся необходимая метаинформация передается в заголовках
Стандартные HTTP-глаголы соответствуют операциям над ресурсом
Обмен данными выполняется в нейтральном формате JSON
Маршруты web.php vs api.php
routes/web.php
Подключает группу middleware web
Сессии, cookies, CSRF-токены, HTML-ответы
routes/api.php
Подключает группу middleware api
Префикс URL /api/, rate limiting (throttle), токены
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Аутентификация API: Laravel Sanctum
Механизм работы Sanctum
Легковесная подсистема выпуска токенов личного доступа
Токены хешируются (SHA-256) в таблице personal_access_tokens
Клиент передает токен в заголовке Authorization: Bearer <token>
Поддерживает установку прав (abilities) и срока жизни токенов
Контроллер выпуска токена
Route ::post ('/tokens/create' , 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' => 'Неверные данные входа' ], 401 );
}
$token = $user ->createToken ('mobile-app' )->plainTextToken;
return response ()->json (['token' => $token ], 200 );
});
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Ресурсные маршруты API
Регистрация apiResource
use App \Http \Controllers \Api \PostApiController ;
Route ::middleware ('auth:sanctum' )->group (function () {
Route ::apiResource ('posts' , PostApiController ::class );
});
В отличие от Route::resource(), метод apiResource() исключает маршруты отображения HTML-форм: create и edit
Спецификация эндпоинтов
Метод
URI
Метод контроллера
Код успешного ответа
GET
/api/posts
index
200 OK
POST
/api/posts
store
201 Created
GET
/api/posts/{id}
show
200 OK
PUT
/api/posts/{id}
update
200 OK
DELETE
/api/posts/{id}
destroy
204 No Content
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Трансформация данных: Eloquent Resources
Зачем нужны ресурсы API?
Прямой возврат моделей Eloquent в JSON раскрывает скрытые поля
Риск утечки чувствительных атрибутов (remember_token, хеши паролей)
Необходимость форматирования дат в ISO 8601 для фронтенда
Добавление вычисляемых атрибутов и ссылок без изменения модели БД
Генерация класса ресурса
php artisan make:resource PostResource
Создаётся файл app/Http/Resources/PostResource.php
Определяет метод toArray(), описывающий структуру JSON
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Реализация класса PostResource
Код PostResource
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 ->body,
'author' => [
'id' => $this ->user->id,
'name' => $this ->user->name,
],
'created_at' => $this ->created_at->toISOString (),
];
}
}
Формат итогового ответа
{
"data" : {
"id" : 15 ,
"title" : "Новая архитектура" ,
"content" : "Текст статьи..." ,
"author" : {
"id" : 3 ,
"name" : "Иван Иванов"
} ,
"created_at" : "2026-10-02T11:00:00.000000Z"
}
}
Laravel автоматически упаковывает результат в корневой ключ data
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Использование ресурсов в контроллере
Отдача единичных записей и коллекций
namespace App \Http \Controllers \Api ;
use App \Http \Controllers \Controller ;
use App \Http \Resources \PostResource ;
use App \Models \Post ;
use Illuminate \Http \Resources \Json \AnonymousResourceCollection ;
class PostApiController extends Controller
{
public function index ( ): AnonymousResourceCollection
{
$posts = Post ::with ('user' )->latest ()->paginate (10 );
return PostResource ::collection ($posts );
}
public function show (Post $post ): PostResource
{
return new PostResource ($post ->load ('user' ));
}
}
Автоматическая пагинация
Метод PostResource::collection() с paginate() автоматически добавляет в ответ служебные мета-данные:
links, meta, current_page, last_page, per_page
Не требует ручного вычисления ссылок пагинации для клиента API
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Работа с файлами: фасад Storage
Архитектура Flysystem
Фасад Storage построен на базе универсальной библиотеки Flysystem
Предоставляет единый программный API для любых типов файловых хранилищ
Смена локального диска на облачный Amazon S3 требует только изменения конфигурации .env без переписывания контроллеров
Базовые методы фасада Storage
use Illuminate \Support \Facades \Storage ;
Storage ::disk ('public' )->put ('reports/summary.txt' , $data );
$content = Storage ::disk ('public' )->get ('reports/summary.txt' );
$exists = Storage ::disk ('public' )->exists ('reports/summary.txt' );
Storage ::disk ('public' )->delete ('reports/summary.txt' );
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Диски хранения и команда storage:link
Конфигурация дисков (config/filesystems.php)
local — каталог storage/app/private/
Доступ закрыт от прямого просмотра через браузер
Используется для закрытых документов, чеков, отчётов
public — каталог storage/app/public/
Публичные пользовательские файлы (аватары, фото товаров)
Доступны через веб-сервер после создания ссылки
Символическая ссылка (Symlink)
php artisan storage:link
Создаёт символическую ссылку:
public/storage → \rightarrow → storage/app/public
Браузер обращается по URL: https://example.com/storage/avatars/image.jpg
Выполняется один раз при первичной настройке проекта
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Контроллер загрузки файлов
Контроллер сохранения аватара
public function updateAvatar (Request $request ): RedirectResponse
{
$request ->validate ([
'avatar' => ['required' , 'image' , 'mimes:jpeg,png,webp' , 'max:2048' ],
]);
if ($request ->hasFile ('avatar' )) {
if ($request ->user ()->avatar_path) {
Storage ::disk ('public' )->delete ($request ->user ()->avatar_path);
}
$path = $request ->file ('avatar' )->store ('avatars' , 'public' );
$request ->user ()->update (['avatar_path' => $path ]);
}
return back ()->with ('status' , 'Аватар успешно обновлён!' );
}
Правила безопасной загрузки
Никогда не использовать исходное имя файла (getClientOriginalName)
Метод store() автоматически генерирует уникальный хеш
Строгая проверка типа image, списка mimes и лимита max в КБ
Генерация URL: Storage::url($user->avatar_path)
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Кэширование данных: фасад Cache
Цели применения кэша
Снижение нагрузки на сервер баз данных при частых запросах
Сокращение времени отдачи ответа клиенту (TTFB) до единиц миллисекунд
Временное сохранение тяжелых агрегированных выборок данных
Основные операции кэширования
use Illuminate \Support \Facades \Cache ;
Cache ::put ('popular_tags' , $tags , now ()->addHour ());
$posts = Cache ::remember ('posts.recent' , 600 , function () {
return Post ::with ('user' )->latest ()->take (10 )->get ();
});
Cache ::forget ('posts.recent' );
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Драйверы кэша и тегирование
Сравнение драйверов кэша
Драйвер
Хранилище
Скорость
Тегирование
file
storage/framework/cache/
Средняя
Нет
database
Таблица cache в БД
Средняя
Нет
redis
In-memory key-value СУБД
Экстремальная
Да
memcached
In-memory key-value
Экстремальная
Да
Тегирование кэша в Redis
Cache ::tags (['posts' , 'category.4' ])->put ('post.12' , $post , 3600 );
Cache ::tags (['posts' ])->flush ();
Позволяет гранулярно сбрасывать связанные группы записей без очистки всего кэша приложения
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Автоматизированное тестирование
Пирамида тестирования
Unit-тесты : тестирование изолированных функций и вспомогательных классов без запуска приложения
Feature-тесты : интеграционные тесты полных HTTP-запросов (роутинг, middleware, контроллер, БД)
Browser-тесты : сквозное тестирование интерфейса в реальном браузере через Laravel Dusk
Pest vs PHPUnit
PHPUnit : классический стандарт объектно-ориентированного тестирования на базе классов
Pest : современный выразительный DSL для тестирования с лаконичным синтаксисом функций
Pest полностью совместим с PHPUnit и предустановлен в Laravel
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Создание Feature-теста для API
Создание файла теста через Artisan
php artisan make:test Api/PostApiTest --pest
Создаётся файл tests/Feature/Api/PostApiTest.php
Проверка запрета неавторизованного доступа
use App \Models \Post ;
use App \Models \User ;
use Illuminate \Foundation \Testing \RefreshDatabase ;
uses (RefreshDatabase ::class );
test ('unauthenticated user cannot create post via API' , function () {
$response = $this ->postJson ('/api/posts' , [
'title' => 'Тестовая статья' ,
'body' => 'Содержимое тестовой статьи' ,
]);
$response ->assertStatus (401 );
});
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Тестирование аутентификации и состояния БД
Проверка успешного сценария с токеном
test ('authorized user creates post through API' , function () {
$user = User ::factory ()->create ();
$payload = [
'title' => 'Промышленная разработка' ,
'body' => 'Детальный текст статьи о тестировании' ,
];
$response = $this ->actingAs ($user , 'sanctum' )
->postJson ('/api/posts' , $payload );
$response ->assertStatus (201 )
->assertJsonPath ('data.title' , 'Промышленная разработка' );
$this ->assertDatabaseHas ('posts' , [
'title' => 'Промышленная разработка' ,
'user_id' => $user ->id,
]);
});
Ключевые утверждения
actingAs($user, 'sanctum') имитирует валидный токен Bearer
assertDatabaseHas() проверяет транзакционную запись в СУБД
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Запуск и анализ тестов
Команды консоли
php artisan test
php artisan test --parallel
php artisan test --coverage --min=80
Изоляция тестового окружения (phpunit.xml)
<php >
<env name ="APP_ENV" value ="testing" />
<env name ="BCRYPT_ROUNDS" value ="4" />
<env name ="CACHE_STORE" value ="array" />
<env name ="DB_CONNECTION" value ="sqlite" />
<env name ="DB_DATABASE" value =":memory:" />
</php >
Тесты работают в оперативной памяти SQLite без затрагивания рабочей базы данных разработки
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Развёртывание приложения (Deployment)
Регламент подготовки к эксплуатации
Установка только боевых зависимостей без dev-пакетов
Предварительная компиляция и кэширование метаинформации
Применение миграций базы данных без ручного подтверждения
Сборка клиентских ассетов через Vite для production
Оптимизация Composer
composer install --no-dev --optimize-autoloader --no-interaction
--no-dev отсекает тестовые утилиты (Pest, Faker, Mockery)
--optimize-autoloader формирует монолитную карту классов classmap, ускоряя поиск файлов PHP
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Производственное кэширование Laravel
Обязательные команды кэширования
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
Критическое правило config:cache!
После выполнения config:cache вызовы функции env('KEY') возвращают null во всех прикладных файлах проекта!
Обращаться к настройкам разрешено только через хелпер config('services.stripe.key')
Для отката кэша в процессе отладки: php artisan optimize:clear
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Чеклист безопасности окружения (.env)
Параметры боевого файла .env
APP_ENV=production
APP_DEBUG=false
Категорически запрещено включать отладку на сервере!
APP_DEBUG=true раскрывает пароли к СУБД, API-ключи и пути на диске при любой ошибке
APP_KEY=base64:... (уникальный ключ шифрования сессий и токенов)
APP_URL=https://myproject.by (обязательно протокол HTTPS)
Команды на сервере
php artisan migrate --force
chmod -R 775 storage bootstrap/cache
Флаг --force принудительно подтверждает миграцию без запроса в интерактивном терминале
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Инфраструктура и серверное окружение
Архитектура стека Nginx + PHP-FPM
Запросы принимает обратный прокси-сервер Nginx
Документ-рут Nginx (root) строго указывает на каталог /public!
Прямой доступ клиентов к ядру, каталогу app и файлу .env физически невозможен
Статические ассеты (CSS, JS, картинки) Nginx отдаёт напрямую
Запросы к PHP передаются через сокет сервиса php8.3-fpm
Платформы развёртывания
PaaS / Managed : Laravel Cloud, Laravel Forge, Render
Автоматизация деплоя из Git, автонастройка SSL Let's Encrypt
Классический VPS : Ubuntu Server 24.04 LTS
Ручная настройка Nginx, демонов Supervisor для очередей и планировщика задач php artisan schedule:run в Cron
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Резюме лекции
Безопасность и валидация
Аутентификация : официальный стартовый набор Laravel Breeze обеспечивает проверенный каркас входа
Авторизация : разделение логики на процедурные Gates и объектные Policies для контроля ресурсов
Валидация : изоляция бизнес-правил в классах FormRequest и отсечение мусорных полей через validated()
API, данные и инфраструктура
RESTful API : токенизация через Laravel Sanctum и стандартизация JSON через API Resources
Хранилище : единый фасад Storage, абстракция Flysystem и раздача публичных файлов через storage:link
Производительность : кэширование через Cache::remember() и инвалидация тегов в Redis
Качество : регрессионные Feature-тесты на Pest с проверкой статусов, структуры JSON и БД
Развёртывание : компиляция конфигураций и строгое отключение отладки APP_DEBUG=false
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Вопросы для контроля знаний
В чём состоит принципиальное отличие HTTP 401 Unauthorized от HTTP 403 Forbidden?
В каких сценариях целесообразно использовать Gate, а в каких — Policy?
Какую угрозу безопасности несёт передача $request->all() в метод Post::create()?
Зачем в кодовой базе RESTful API используется слой Eloquent API Resources?
Какую практическую задачу решает консольная команда php artisan storage:link?
Почему в боевой рабочей среде критически важно выставить APP_DEBUG=false?
Что произойдет при попытке вызова функции env('KEY') после команды config:cache?
Чем отличается запуск Feature-теста с трейтом RefreshDatabase от обычного теста?
Лекция 4. Продвинутые темы Laravel
Разработка веб-приложений с использованием программных платформ
Полезные ресурсы и документация
Безопасность и архитектура
Laravel Starter Kits — laravel.com/docs/starter-kits
Laravel Authorization — laravel.com/docs/authorization
Laravel Validation — laravel.com/docs/validation
Laravel Sanctum — laravel.com/docs/sanctum
Хранилище, тесты и деплой
Laravel File Storage — laravel.com/docs/filesystem
Laravel Cache — laravel.com/docs/cache
Pest PHP Testing Framework — pestphp.com
Laravel Deployment Guide — laravel.com/docs/deployment
Лекция 4. Продвинутые темы Laravel
Лекция 4, 2 академических часа. Цель: сформировать у студентов практические навыки реализации защищённых корпоративных веб-систем: комплексная аутентификация и авторизация, чистая валидация входных данных через Form Request, проектирование stateless RESTful API с токенами Sanctum, безопасная работа с файловыми хранилищами, оптимизация через кэширование, написание автоматических тестов и регламент подготовки к промышленному развёртыванию (production deployment).
Связь с предыдущими темами: продолжает лекцию 3 («Основы Laravel: архитектура, маршрутизация, Blade и Eloquent») и базируется на протоколе HTTP и принципах безопасности из лекций 1 и 2. Материал завершает блок изучения Laravel перед переходом к компонентам Symfony.
Методика: 50 минут лекционный разбор архитектуры, 25 минут живая демонстрация ключевых сценариев в консоли и API-клиенте, 15 минут разбор типовых ошибок и контрольные вопросы.
Докладчик: Подчеркните, что предыдущая лекция дала базовый работающий макет, но реальная промышленная веб-разработка начинается именно на этом этапе, когда в проект закладываются безопасность, тестирование и масштабируемость.
Докладчик: Сравните два подхода. Покажите, что учебный макет хорош для первого знакомства, но отдавать его в промышленную эксплуатацию категорически запрещено из-за уязвимостей и архитектурного долга.
Докладчик: Отметьте, что в Laravel не нужно вручную писать хеширование паролей и обработчики сессий входа. Официальные стартовые наборы экономят сотни часов рутины и закрывают векторы атак.
Докладчик: Обратите внимание студентов на то, что Breeze не прячет код внутри vendor-директории, а генерирует чистые контроллеры и шаблоны прямо в проекте.
Докладчик: Покажите, как middleware перенаправляет неавторизованного пользователя на страницу /login и сохраняет URL намерения (intended URL) для возврата после успешного входа.
Докладчик: Подчеркните эту границу! Студенты постоянно путают 401 и 403. 401 означает «мы вас не знаем, представьтесь», а 403 — «мы знаем, кто вы, но вам сюда нельзя».
Докладчик: Gates отлично подходят для общих глобальных действий, не привязанных к конкретной модели Eloquent (доступ в панель управления, просмотр отчетов за месяц).
Докладчик: Политики группируют правила вокруг конкретной бизнес-сущности. Обратите внимание, что первым аргументом Laravel всегда автоматически передаёт текущего аутентифицированного пользователя.
Докладчик: Обязательно укажите, что сокрытие кнопки в интерфейсе через @can не заменяет проверку $this->authorize() в контроллере! Злоумышленник может отправить запрос вручную через cURL.
Докладчик: Объясните, что контроллер должен быть тонким дирижером. Его задача — принять запрос, вызвать сервис или модель и вернуть ответ, а не валидировать массивы.
Докладчик: Подчеркните, что если проверка прав не нужна внутри Form Request (например, маршрут уже защищен middleware auth), метод authorize() должен явно возвращать true.
Докладчик: Расскажите о правилах валидации exists и unique. Они автоматически делают SQL-запрос к базе для подтверждения валидности внешних ключей.
Докладчик: Категорически запретите использовать $request->all() при создании моделей. Злоумышленник может дописать в HTTP-запрос 'is_admin' => 1 и получить права суперпользователя.
Докладчик: Объясните разницу между веб-приложением для браузера и API. Браузеру нужны HTML и сессионные куки. Мобильному приложению или фронтенду на React/Vue нужен только чистый JSON.
Докладчик: Обратите внимание: метод plainTextToken возвращает открытый токен ровно один раз при генерации. В базе хранится только его криптографический хеш.
Докладчик: Подчеркните стандартные коды ответов HTTP. Создание ресурса возвращает 201 Created, удаление без тела — 204 No Content, ошибка валидации — 422 Unprocessable Content.
Докладчик: API Resource — это слой представления (View) для REST API. Он выступает контрактом между внутренней структурой базы данных и внешним миром.
Докладчик: Обратите внимание, что мы переименовали поле 'body' в 'content'. Это наглядно демонстрирует, как API Resource изолирует клиентов API от схемы таблиц базы данных.
Докладчик: Обратите внимание на вызов Post::with('user'). Это предотвращает проблему N+1 запросов при сериализации автора каждого поста в цикле коллекции.
Докладчик: Подчеркните, что в PHP-коде никогда не следует использовать прямые функции вроде file_put_contents() или move_uploaded_file() с жестко заданными абсолютными путями.
Докладчик: Это частая ошибка студентов! Без команды storage:link файлы загружаются в storage/app/public, но браузер получает ошибку 404, пытаясь загрузить картинку по URL.
Докладчик: Объясните опасность сохранения оригинального имени файла: атака Path Traversal, перезапись существующих файлов и выполнение вредоносных скриптов при ошибочной конфигурации веб-сервера.
Докладчик: Метод Cache::remember() — наиболее элегантный инструмент Laravel. Он автоматически проверяет наличие ключа, а если его нет — выполняет замыкание, сохраняет результат и возвращает его.
Докладчик: Для учебных проектов подходит драйвер file. В высоконагруженных промышленных проектах стандартом де-факто является Redis благодаря поддержке атомарных операций и тегов.
Докладчик: Подчеркните студентам, что Feature-тесты в веб-разработке дают максимальную отдачу на затраченное время, так как они эмулируют реальный HTTP-запрос пользователя от начала до конца.
Докладчик: Обратите внимание на трейт RefreshDatabase. Он автоматически применяет миграции к тестовой БД и оборачивает каждый тест в транзакцию с последующим откатом (rollback).
Докладчик: Метод actingAs() избавляет от необходимости вручную выпускать токен через HTTP-запрос логина в каждом тесте, значительно ускоряя прогон тестового набора.
Докладчик: Настройка BCRYPT_ROUNDS=4 для тестирования драматически ускоряет выполнение тестов с пользователями, так как хеширование паролей не тратит процессорное время.
Докладчик: Развертывание PHP-приложений кардинально отличается от локальной разработки. На сервере никогда не должен запускаться npm run dev или composer require --dev.
Докладчик: Подчеркните это правило трижды! 90% начинающих разработчиков при деплое сталкиваются с тем, что env() внезапно возвращает null, если они забыли о config:cache.
Докладчик: Утечка отладочного экрана Ignition при APP_DEBUG=true — одна из самых частых причин взлома веб-приложений. На боевом сервере пользователь должен видеть только нейтральную страницу ошибки 500.
Докладчик: Напомните студентам, что веб-сервер никогда не должен смотреть в корень проекта Laravel. Только в подпапку /public! Иначе весь исходный код и файл .env с паролями окажутся в открытом доступе.
Докладчик: Обобщите изученный блок. Студенты теперь владеют всеми компонентами, которые отделяют студенческую поделку от коммерческого веб-сервиса уровня Middle-разработчика.
Докладчик: Задайте 2-3 вопроса аудитории для оперативной проверки усвоения материала. Разберите логику ответа на вопрос о разнице между 401 и 403, а также опасность $request->all().
Докладчик: Рекомендуйте студентам официальную документацию Laravel как главный источник актуальных стандартов. На следующем занятии мы переходим к фреймворку Symfony и сравним их архитектурные подходы.