Комментарии (2)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Конечно, покажу реальный код, который иллюстрирует несколько ключевых концепций PHP и современного Backend-разработки. Это будет модуль аутентификации пользователя с использованием Object-Oriented Programming (OOP), взаимодействием с базой данных через PDO, и реализацией JWT (JSON Web Token) для безопасного API. Этот код демонстрирует структуру, безопасность и профессиональные практики.
Пример: Класс аутентификации пользователя с JWT
<?php
declare(strict_types=1);
namespace App\Security;
use PDO;
use RuntimeException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
/**
* Класс AuthService отвечает за регистрацию, логин и верификацию пользователей через JWT.
* Использует PDO для безопасной работы с базой данных и библиотеку firebase/php-jwt.
*/
class AuthService
{
private PDO $db;
private string $jwtSecretKey;
private string $jwtAlgorithm = 'HS256';
public function __construct(PDO $db, string $jwtSecretKey)
{
$this->db = $db;
$this->jwtSecretKey = $jwtSecretKey;
}
/**
* Регистрация нового пользователя.
* @param string $email
* @param string $password
* @return array Возвращает массив с ID пользователя и статусом.
* @throws RuntimeException Если пользователь уже существует или произошла ошибка БД.
*/
public function register(string $email, string $password): array
{
// Проверка существования пользователя
$stmt = $this->db->prepare("SELECT id FROM users WHERE email = :email");
$stmt->execute([':email' => $email]);
if ($stmt->fetch()) {
throw new RuntimeException('Пользователь с таким email уже существует.');
}
// Создание хэша пароля с использованием современного алгоритма bcrypt
$passwordHash = password_hash($password, PASSWORD_BCRYPT);
// Вставка нового пользователя в БД
$stmt = $this->db->prepare("INSERT INTO users (email, password_hash) VALUES (:email, :password_hash)");
$stmt->execute([
':email' => $email,
':password_hash' => $passwordHash
]);
$userId = (int)$this->db->lastInsertId();
return ['user_id' => $userId, 'status' => 'registered'];
}
/**
* Аутентификация пользователя и генерация JWT токена.
* @param string $email
* @param string $password
* @return string Возвращает JWT токен для дальнейшего использования в API.
* @throws RuntimeException Если аутентификация не успешна.
*/
public function login(string $email, string $password): string
{
$stmt = $this->db->prepare("SELECT id, password_hash FROM users WHERE email = :email");
$stmt->execute([':email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user || !password_verify($password, $user['password_hash'])) {
throw new RuntimeException('Неверный email или пароль.');
}
// Генерация payload для JWT с пользовательскими данными и временем жизни
$payload = [
'user_id' => (int)$user['id'],
'email' => $email,
'iat' => time(), // Issued At: время создания токена
'exp' => time() + (60 * 60) // Expiration: токен живёт 1 час
];
// Генерация и возврат JWT токена
return JWT::encode($payload, $this->jwtSecretKey, $this->jwtAlgorithm);
}
/**
* Верификация и декодирование JWT токена из заголовка Authorization.
* @param string $authHeader Значение заголовка "Bearer <token>"
* @return array Возвращает декодированный payload токена.
* @throws RuntimeException Если токен невалидный, просрочен или заголовок отсутствует.
*/
public function verifyToken(string $authHeader): array
{
if (!preg_match('/Bearer\s+(.*)$/', $authHeader, $matches)) {
throw new RuntimeException('Отсутствует или некорректный Authorization заголовок.');
}
$jwt = $matches[1];
try {
// Декодирование и верификация токена с использованием секретного ключа
$decoded = JWT::decode($jwt, new Key($this->jwtSecretKey, $this->jwtAlgorithm));
return (array)$decoded;
} catch (\Exception $e) {
throw new RuntimeException('Невалидный или просроченный JWT токен: ' . $e->getMessage());
}
}
}
Пример использования класса в контроллере API (например, для endpoint /api/login)
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Security\AuthService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class AuthController
{
private AuthService $authService;
public function __construct(AuthService $authService)
{
$this->authService = $authService;
}
/**
* Обработка POST запроса на /api/login
*/
public function login(ServerRequestInterface $request): ResponseInterface
{
$body = $request->getParsedBody(); // Предполагается, что используется PSR-7
$email = $body['email'] ?? '';
$password = $body['password'] ?? '';
try {
$jwtToken = $this->authService->login($email, $password);
// Возвращаем успешный ответ с токеном в формате JSON
$response = new JsonResponse([
'success' => true,
'token' => $jwtToken,
'message' => 'Аутентификация успешна.'
]);
return $response->withHeader('Content-Type', 'application/json');
} catch (RuntimeException $e) {
// Возвращаем ошибку клиента в формате JSON
return new JsonResponse([
'success' => false,
'message' => $e->getMessage()
], 401); // HTTP статус 401 Unauthorized
}
}
}
Ключевые моменты, демонстрируемые в этом коде:
- Современный PHP (
strict_types=1): Использование строгой типизации для повышения надежности. - Объектно-ориентированный подход: Логика инкапсулирована в классе
AuthService, что обеспечивает повторное использование и тестируемость. - Безопасность:
* **Хэширование паролей**: Используется `password_hash()` с алгоритмом `PASSWORD_BCRYPT`, который является текущим стандартом.
* **JWT (JSON Web Tokens)**: Токены используются для stateless аутентификации в API, содержат payload и защищены секретным ключом.
* **PDO (PHP Data Objects)**: Для всех SQL операций используется подготовленные запросы (`prepare`/`execute`), что предотвращает **SQL Injection**.
- Профессиональная структура:
* Четкое разделение ответственности: Сервис (`AuthService`) обрабатывает бизнес-логику, Контроллер (`AuthController`) — HTTP взаимодействие.
* Использование исключений (`RuntimeException`) для обработки ошибок и чистого управления потоком.
* Предполагается использование **PSR-7** (`ServerRequestInterface`, `ResponseInterface`) для стандартизации HTTP, что характерно для современных фреймворков (Symfony, Slim).
- Практики реального мира:
* Токены имеют время жизни (`exp`), что важно для безопасности.
* Метод `verifyToken` предназначен для middleware, который будет проверять токен перед каждым защищенным API запросом.
Этот код — пример того, как современный PHP Backend разработчик структурирует сервисы, обеспечивает безопасность и интегрирует стандартные библиотеки для решения распространенных задач, таких как аутентификация пользователей.