DefaultUser Class

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);
    }
}