Files
testRestApi/src/Controller/Api/AuthController.php
T
2026-10-21 18:34:35 +02:00

94 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Controller\Api;
use Authentication\Authenticator\FormAuthenticator;
use Cake\Core\Configure;
use Cake\Event\EventInterface;
use Cake\Http\Exception\UnauthorizedException;
use Cake\Http\Response;
use Cake\I18n\DateTime;
use Firebase\JWT\JWT;
/**
* Authentication endpoints: login (JWT issue) and own profile.
*/
class AuthController extends ApiController
{
/**
* @param \Cake\Event\EventInterface<\Cake\Controller\Controller> $event Event
* @return void
*/
public function beforeFilter(EventInterface $event): void
{
parent::beforeFilter($event);
$this->Authentication->allowUnauthenticated(['login']);
}
/**
* POST /api/auth/login - exchange email + password for a JWT.
*
* @return \Cake\Http\Response
*/
public function login(): Response
{
$this->request->allowMethod(['post']);
// A token is issued only for email/password credentials, never in exchange for another token.
$result = $this->Authentication->getResult();
$provider = $this->Authentication->getAuthenticationService()->getAuthenticationProvider();
if ($result === null || !$result->isValid() || !$provider instanceof FormAuthenticator) {
throw new UnauthorizedException('Invalid email or password.');
}
/** @var \App\Model\Entity\User $user */
$user = $result->getData();
$user->last_login = DateTime::now();
$this->fetchTable('Users')->saveOrFail($user);
$ttl = (int)Configure::read('Jwt.ttl', 3600);
$now = time();
$token = JWT::encode([
'iss' => 'testRestApi',
'sub' => $user->id,
'role' => $user->role,
'iat' => $now,
'exp' => $now + $ttl,
], (string)Configure::read('Jwt.secret'), 'HS256');
return $this->respond([
'token' => $token,
'token_type' => 'Bearer',
'expires_in' => $ttl,
'user' => $user,
]);
}
/**
* GET /api/auth/me - current user's profile.
* PUT|PATCH /api/auth/me - update own profile (name, email, password).
*
* @return \Cake\Http\Response
*/
public function me(): Response
{
$this->request->allowMethod(['get', 'put', 'patch']);
$usersTable = $this->fetchTable('Users');
$user = $usersTable->get($this->currentUser()->id);
if ($this->request->is('get')) {
return $this->respond($user);
}
$user = $usersTable->patchEntity($user, (array)$this->request->getData(), [
'fields' => ['email', 'password', 'first_name', 'last_name'],
]);
if (!$usersTable->save($user)) {
return $this->respondValidationError($user);
}
return $this->respond($user);
}
}