If the user is created successfully after each authentication, a class named Olobase\Mezzio\Authentication\DefaultUser is created and this class is immutable.
<?php
declare(strict_types=1);
namespace Olobase\Mezzio\Authentication;
use Mezzio\Authentication\UserInterface;
/**
* Default implementation of UserInterface.
*
* This implementation is modeled as immutable, to prevent propagation of
* user state changes.
*
* We recommend that any details injected are serializable.
*/
final class DefaultUser implements UserInterface
{
/**
* User id
* @var string
*/
private $id;
/**
* User email
* @var string
*/
private $identity;
/**
* User roles
* @var string[]
*/
private $roles;
/**
* User details
* @var array
*/
private $details;
/**
* Constuctor
*
* @param string $id user_id
* @param string $identity user email
* @param array $roles user roles for frontend
* @param array $details extra details
*/
public function __construct(
string $id,
string $identity,
array $roles = [],
array $details = []
)
{
$this->id = $id;
$this->identity = $identity;
$this->roles = $roles;
$this->details= $details;
}
public function getId() : string
{
return $this->id;
}
public function getIdentity() : string
{
return $this->identity;
}
public function getRoles() : array
{
return $this->roles;
}
public function getDetails() : array
{
return $this->details;
}
public function getDetail(string $name, $default = null)
{
return isset($this->details[$name]) ? $this->details[$name] : $default;
}
}
The following example shows the content of the App\Middleware\JwtAuthenticationMiddleware class.
declare(strict_types=1);
namespace App\Middleware;
use Mezzio\Authentication\UserInterface;
use Mezzio\Authentication\AuthenticationInterface;
use Firebase\JWT\ExpiredException;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Laminas\I18n\Translator\TranslatorInterface as Translator;
class JwtAuthenticationMiddleware implements MiddlewareInterface
{
/**
* @var AuthenticationInterface
*/
protected $auth;
public function __construct(AuthenticationInterface $auth, Translator $translator)
{
$this->auth = $auth;
$this->translator = $translator;
}
/**
* {@inheritDoc}
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{
try {
$user = $this->auth->authenticate($request);
if (null !== $user) {
return $handler->handle($request->withAttribute(UserInterface::class, $user));
}
} catch (ExpiredException $e) {
// 401 Unauthorized response
// Response Header = 'Token-Expired: true'
return new JsonResponse(['data' => ['error' => $this->translator->translate('Token Expired')]], 401, ['Token-Expired' => 1]);
}
return $this->auth->unauthorizedResponse($request);
}
}
If the authentication is successful, the DefaultUser class is obtained with the $this->auth->authenticate() method; and the resulting object is recorded as a Mezzio\Authentication\UserInterface attribute in the $request class with the http middleware, ensuring that the user object can be obtained globally in all middlewares.
$request->withAttribute(UserInterface::class, $user); // Set user
You can access the information of the authenticated user assigned to the Request class from a handler class as follows.
$user = $request->getAttribute(UserInterface::class); // get DefaultUser Class
$userId = $user->getId(); // get id from current user
In the following example, the user's ID value is obtained in the FindMeHandler class.
src/App/Handler/Account/FindMeHandler.php
<?php
declare(strict_types=1);
namespace App\Handler\Account;
use App\Model\AccountModel;
use Olobase\Mezzio\DataManagerInterface;
use App\Schema\Account\AccountFindMe;
use Mezzio\Authentication\UserInterface;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class FindMeHandler implements RequestHandlerInterface
{
public function __construct(
private AccountModel $accountModel,
private DataManagerInterface $dataManager
)
{
$this->dataManager = $dataManager;
$this->accountModel = $accountModel;
}
/**
* @OA\Get(
* path="/account/findMe",
* tags={"Account"},
* summary="Find my account data",
* operationId="account_findOneById",
*
* @OA\Response(
* response=200,
* description="Successful operation",
* @OA\JsonContent(ref="#/components/schemas/AccountFindMe"),
* )
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$user = $request->getAttribute(UserInterface::class); // get user from current token
$userId = $user->getId();
$row = $this->accountModel->findMe($userId);
if ($row) {
$data = $this->dataManager->getViewData(
AccountFindMe::class,
$row
);
return new JsonResponse($data);
}
return new JsonResponse([], 404);
}
}