Аутентификация
Аутентификация — это процесс проверки личности пользователя. Представьте, что вы входите в здание по пропуску: система проверяет, кто вы и есть ли у вас доступ. В Imhotep аутентификация работает так же — система проверяет учетные данные пользователя и предоставляет доступ к защищенным ресурсам.
Imhotep предлагает гибкую систему аутентификации с поддержкой нескольких guards (стражей) и user providers (провайдеров пользователей). Это позволяет использовать разные способы аутентификации для разных частей вашего приложения.
Конфигурирование
Все настройки аутентификации находятся в файле config/auth.php. Этот файл содержит несколько ключевых разделов:
-
guards (стражи), определяют, как происходит аутентификация — через сессии, токены или другие методы. -
providers (провайдеры), определяют, откуда берутся пользователи — из базы данных, массива или других источников. -
default, указывает, какой страж используются по умолчанию.
Стражи аутентификации
Стражи определяют, как будет происходить аутентификация. Imhotep поставляется с несколькими готовыми стражами:
Session Guard
Использует сессии для хранения информации об аутентификации. Идеально подходит для веб-приложений с традиционными формами входа.
// config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
'remember' => 1209600, // Время жизни "запомнить меня" в секундах (2 недели)
],
],
Token Guard
Использует токены для аутентификации. Подходит для API и мобильных приложений.
// config/auth.php
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'input_key' => 'api_token', // Ключ, по которому искать токен
'storage_key' => 'api_token', // Поле в базе данных для хранения токена
'hash' => false, // Хранить токен в хешированном виде
],
],
Провайдеры пользователей
Провайдеры определяют, как система получает данные о пользователях.
Database Provider
Получает пользователей из базы данных.
// config/auth.php
'providers' => [
'users' => [
'driver' => 'database',
'table' => 'users',
'user' => App\Models\User::class, // Опционально: класс модели пользователя
],
],
Array Provider
Использует массив пользователей, идеально для тестирования или некритичных систем.
// config/auth.php
'providers' => [
'admins' => [
'driver' => 'array',
'users' => [
'admin@example.com' => [
'id' => 1,
'email' => 'admin@example.com',
'password' => 'password123',
'name' => 'Admin',
],
],
],
],
Модель пользователя
Для использования аутентификации ваша модель пользователя должна реализовывать интерфейс Imhotep\Contracts\Auth\Authenticatable. Проще всего использовать трейт Imhotep\Auth\Traits\Authenticatable:
namespace App\Models;
use Imhotep\Auth\Traits\Authenticatable;
use Imhotep\Contracts\Auth\Authenticatable as AuthenticatableContract;
class User implements AuthenticatableContract
{
use Authenticatable;
// Получить имя первичного ключа
// public function getAuthIdName(): string;
// Получить значение первичного ключа
// public function getAuthId(): mixed;
// Получить хешированный пароль
// public function getAuthPassword(): string;
// Получить токен "запомнить меня"
// public function getRememberToken(): ?string;
// Установить токен "запомнить меня"
// public function setRememberToken(string $value): void;
// Получить имя поля для токена "запомнить меня"
// public function getRememberTokenName(): string;
}
Аутентификация в действии
Ручной вход
Для входа пользователя используется фасад Auth:
namespace App\Controllers;
use App\Models\User;
use Imhotep\Facades\Hash;
use Imhotep\Facades\Auth;
use Imhotep\Http\Request;
class AuthController
{
public function login(Request $request)
{
$email = $request->post('email');
$password = $request->post('password');
$remember = (bool) $request->post('remember', false);
$user = User::email($email)->first();
if (!$user || !Hash::check($password, $user->password)) {
return response()->json(['error' => 'Неверные учетные данные'], 401);
}
// Аутентифицируем пользователя
Auth::login($user, $remember);
return response()->json(['message' => 'Добро пожаловать!']);
}
}
Вход с проверкой учетных данных
Метод attempt проверяет учетные данные и автоматически выполняет вход:
namespace App\Controllers;
use Imhotep\Facades\Auth;
use Imhotep\Http\Request;
class AuthController
{
public function login(Request $request)
{
$credentials = $request->only(['email', 'password']);
$remember = (bool) $request->post('remember', false);
if (Auth::attempt($credentials, $remember)) {
// Вход выполнен успешно
return response()->json(['message' => 'Добро пожаловать!']);
}
return response()->json(['error' => 'Неверные учетные данные'], 401);
}
}
Вход по ID
namespace App\Controllers;
use App\Models\User;
use Imhotep\Facades\Auth;
class AuthController
{
public function loginAsUser(int $id)
{
$user = User::find($id);
if ($user && Auth::loginUsingId($id)) {
return response()->json(['message' => 'Вы вошли как ' . $user->name]);
}
return response()->json(['error' => 'Пользователь не найден'], 404);
}
}
Выход из системы
namespace App\Controllers;
use Imhotep\Facades\Auth;
class AuthController
{
public function logout()
{
Auth::logout();
return response()->json(['message' => 'Вы вышли из системы']);
}
}
Проверка статуса пользователя
// Проверить, аутентифицирован ли пользователь
if (Auth::check()) {
// Пользователь вошел
}
// Проверить, не аутентифицирован ли пользователь
if (Auth::guest()) {
// Пользователь не вошел
}
// Получить текущего пользователя
$user = Auth::user();
// Получить ID текущего пользователя
$userId = Auth::id();
// Проверить, есть ли установленный пользователь
if (Auth::hasUser()) {
// Пользователь установлен
}
Защита маршрутов
Использование middleware
Защитите маршруты с помощью middleware auth:
// В файле routes/web.php или routes/api.php
Route::get('/profile', 'ProfileController@index')
->middleware('auth');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth');
// С указанием конкретного стража
Route::get('/admin', 'AdminController@index')
->middleware('auth:admin');
Использование конкретного стража
// Явное указание стража
$user = Auth::guard('api')->user();
// Проверка через конкретный страж
if (Auth::guard('web')->check()) {
// Пользователь аутентифицирован через web страж
}
Функция "Запомнить меня"
Для реализации "запомнить меня" используйте параметр remember:
public function login(Request $request)
{
$credentials = $request->only(['email', 'password']);
$remember = $request->has('remember');
if (Auth::attempt($credentials, $remember)) {
// Вход выполнен с сохранением сессии
return redirect()->intended('dashboard');
}
}
В модели пользователя должен быть определено поле для хранения токена:
use Imhotep\Auth\Traits\Authenticatable;
use Imhotep\Contracts\Auth\Authenticatable as AuthenticatableContract;
class User implements AuthenticatableContract
{
use Authenticatable;
protected string $rememberToken = 'remember_token'; // Имя поля в БД
// Если у вас другое имя поля, установите его
public function setRememberTokenName(string $name): void
{
$this->rememberToken = $name;
}
}
HTTP Basic Authentication
Для быстрой защиты API можно использовать HTTP Basic Authentication:
// В контроллере
use Imhotep\Auth\Middleware\AuthenticateBasic;
use Imhotep\Facades\Auth;
public function getData(Request $request)
{
// Добавьте middleware
return response()->json(['data' => 'Защищенные данные']);
}
// В routes.php
Route::get('/api/data', 'DataController@getData')
->middleware('auth.basic');
// С указанием поля для email
Route::get('/api/data', 'DataController@getData')
->middleware('auth.basic:web,email');
События аутентификации
Imhotep генерирует события при различных действиях с аутентификацией. Вы можете подписаться на них для дополнительной логики:
namespace App\Listeners;
use Imhotep\Auth\Events\Login;
use Imhotep\Auth\Events\Logout;
use Imhotep\Auth\Events\Authenticated;
use Imhotep\Auth\Events\Attempting;
use Imhotep\Auth\Events\Failed;
use Imhotep\Auth\Events\Validated;
use Imhotep\Auth\Events\Registered;
class AuthEventListener
{
public function onLogin(Login $event)
{
Log::info('Пользователь вошел', [
'user_id' => $event->user?->getAuthId(),
'guard' => $event->guard,
'remember' => $event->remember
]);
}
public function onLogout(Logout $event)
{
Log::info('Пользователь вышел', [
'user_id' => $event->user->getAuthId(),
'guard' => $event->guard
]);
}
public function onAuthenticated(Authenticated $event)
{
// Пользователь аутентифицирован
}
public function onAttempting(Attempting $event)
{
// Попытка аутентификации
Log::info('Попытка входа', [
'credentials' => array_keys($event->credentials),
'remember' => $event->remember
]);
}
public function onFailed(Failed $event)
{
// Неудачная попытка аутентификации
Log::warning('Неудачный вход', [
'user_id' => $event->user?->getAuthId(),
'credentials' => array_keys($event->credentials)
]);
}
public function onValidated(Validated $event)
{
// Учетные данные проверены успешно
}
public function onRegistered(Registered $event)
{
// Пользователь зарегистрирован
}
}
Создание собственных провайдеров пользователей
Аналогично, вы можете создать свой провайдер пользователей:
// В сервис-провайдере
use Imhotep\Contracts\Auth\Factory;
class AuthServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->app->make(Factory::class)->extendProvider('custom', function ($app, $config) {
return new CustomUserProvider($config);
});
}
}
Рекомендации
- Всегда хешируйте пароли — используйте
Hash::make()перед сохранением. - Используйте CSRF-защиту для веб-форм входа.
- Ограничьте попытки входа для защиты от брутфорса.
- Используйте HTTPS в production для защиты учетных данных.
- Регулярно обновляйте ключи шифрования сессий.