init
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user