Introduction
This component provides authentication abstraction using a middleware approach for PSR-7 and PSR-15 applications.
Authentication is performed using the AuthenticationMiddleware
class. This middleware consumes an AuthenticationInterface
adapter to check if a PSR-7 request is
authenticated or not. If authenticated, the middleware executes the next
middleware in the application, passing a UserInterface
object via a request attribute. If the request is not authenticated, the
middleware returns a 401 Unauthorized
response based on the authentication
adapter provided.
The Mezzio\Authentication\UserInterface
is defined as follows:
namespace Mezzio\Authentication;
interface UserInterface
{
/**
* Get the unique user identity (id, username, email address, etc.).
*/
public function getIdentity() : string;
/**
* Get all user roles.
*
* @return string[]
*/
public function getRoles() : array;
/**
* Get the detail named $name if present; return $default otherwise.
*/
public function getDetail(string $name, $default = null);
/**
* Get all additional user details, if any.
*/
public function getDetails() : array;
}
The UserInterface
attribute in the PSR-7 request can be used for checking
if a user has been authenticated or not, e.g. it can be used to verify the
authorization level of a user (for this scope, it is consumed by
mezzio-authorization).
For example:
// Retrieve the UserInterface object from the request.
$user = $request->getAttribute(UserInterface::class);
// Retrieve the user's identity.
$user->getIdentity();
// Retrieve the user's roles (if any).
$user->getRoles();
// Retrieve the user's other details (if any).
$user->getDetails();
Default User Class
We provide a default implementation of UserInterface
via the class
Mezzio\Authentication\DefaultUser
. The class is final and immutable,
in order to prevent runtime changes.
Repositories will fetch user information based on the identity, including any associated roles, and optionally any additional details (full name, email, profile information, etc.). Often, user data and the objects representing them are unique to the application. As such, the default repository implementations we provide allow you to inject a factory for producing the user. This factory should be a PHP callable with the following signature:
function (string $identity, array $roles = [], array $details = []) : UserInterface
In order to notify the package to use your custom factory, you will need to
create a service factory that returns it, and map it to the
Mezzio\Authentication\UserInterface
service.
We provide a service factory named Mezzio\Authentication\DefaultUserFactory
that returns a user factory that produces a DefaultUser
instance from the
arguments provided. This is mapped as follows in the service configuration:
use Mezzio\Authentication\DefaultUserFactory;
use Mezzio\Authentication\UserInterface;
return [
// ...
'dependencies' => [
'factories' => [
// ...
// Change the DefaultUserFactory::class with your custom service
// factory that produces a user factory:
UserInterface::class => DefaultUserFactory::class
]
]
];
Usage in the Route
The AuthenticationMiddleware
can be used to authenticate a route. You just
need to add the class name of the middleware in the pipeline of a route.
As an example:
$app->get('/admin/dashboard', [
Mezzio\Authentication\AuthenticationMiddleware::class,
Admin\Action\Dashboard::class
], 'admin.dashboard');
In this example, the AuthenticationMiddleware
is executed as first middleware
of the route admin.dashboard
. If the user is authenticated, the application
executes the Dashboard
action; otherwise it returns a 401 Unauthorized
response.
Choosing an Authentication Adapter
You can choose an authentication adapter and a user repository through the service container configuration.
You need to specify the service for authentication using the name
Mezzio\Authentication\AuthenticationInterface
and the user registry
using the service name Mezzio\Authentication\UserRepositoryInterface::class
.
For instance, using laminas-servicemanager
you can easily configure these two
services using aliases
. Below is an example of configuration using the HTTP
Basic Access Authentication adapter and the htpasswd file as the user
repository.
use Mezzio\Authentication\AuthenticationInterface;
use Mezzio\Authentication\Basic;
use Mezzio\Authentication\UserRepository;
use Mezzio\Authentication\UserRepositoryInterface;
return [
// ...
'dependencies' => [
// ...
'aliases' => [
// ...
AuthenticationInterface::class => Basic\BasicAccess::class,
UserRepositoryInterface::class => UserRepository\Htpasswd::class
]
]
];