Derafu: Auth

GitHub GitHub last commit CI Workflow Total Downloads

Authentication and authorization for PHP applications, built on the PSR-15 middleware of Mezzio: mezzio-authentication, mezzio-authorization, mezzio-session and mezzio-flash. It keeps authentication (who is asking) apart from authorization (may they enter), and it has two channels (the web, with a session, and the API, with the credentials in the header) and three providers, of which the application uses one (see How it works):

Provider Who knows the users Page
Keycloak A Keycloak server: OpenID Connect, authorization code flow with PKCE. Keycloak
Database A table of a database, with the hash of the password. Database
Htpasswd An .htpasswd file, with bcrypt hashes: only a username and a password. Htpasswd

What it gives

  • Authentication middleware with the user in the request, and the unauthorized response when there is none: a redirect (to Keycloak, or to the login), or a JSON 401 with WWW-Authenticate for the API paths, where the client sends its credentials in the header (see API).
  • Login and logout as the way in and the way out: they are handled before looking at what is protected, the session id is renewed (against session fixation) and the logout is a POST of the same origin (against CSRF).
  • Keycloak done by the standard: state, nonce and PKCE, the tokens verified with the keys of the realm (cached), the refresh of the tokens, and the logout that ends the session in Keycloak too.
  • Database provider: the login form (protected with a CSRF token and a captcha), the limit of failed attempts, the hash made again when its algorithm is old, and a user that does not exist takes as long as one that does.
  • Protected paths by prefix, with the roles that each one needs. A route can declare its own roles, which also protect its path, and the roles of the site win over the ones of a route that it imports.
  • Account pages for every provider: a login route, a profile page (data, API and session), with templates that a site can override (see Profile). With Keycloak, the user makes API tokens there.
  • Translatable: the messages, the flash messages and the login form have their translation (Spanish ships with the package).

Quick start (Keycloak)

The libraries of the provider are not required by the package, because the database provider does not need them:

composer require derafu/auth league/oauth2-client firebase/php-jwt

Import the services and the routes:

# config/services.yaml
imports:
    - { resource: '../vendor/derafu/auth/resources/config/auth-services.yaml' }
# config/routes.yaml
imports:
    - { resource: '../vendor/derafu/auth/resources/config/auth-routes.yaml' }

For Derafu HTTP or Foundation, import auth-http-services.yaml instead: it adds the authentication and authorization middlewares to the shared pipeline in order, without copying the request handler configuration. For another PSR-15 pipeline, attach the middlewares as described in Configuration. Configure the environment (see Configuration for every variable):

AUTH_PROVIDER=keycloak
AUTH_KEYCLOAK_URL=https://auth.example.com
AUTH_KEYCLOAK_REALM=my-realm
AUTH_KEYCLOAK_CLIENT_ID=my-app
AUTH_KEYCLOAK_CLIENT_SECRET=the-secret
AUTH_KEYCLOAK_WEB_REDIRECT_URI=https://app.example.com/auth/callback
AUTH_PROTECTED_PATHS='["/dashboard", "/admin"]'

And configure the client in Keycloak as Keycloak says (redirect URI, post logout redirect URI and PKCE).

Access the user

The authentication middleware puts the user in the request, with the name of the interface of Mezzio:

use Mezzio\Authentication\UserInterface;

$user = $request->getAttribute(UserInterface::class);

if ($user !== null && !$user->isAnonymous()) {
    $identity = $user->getIdentity();
    $roles = $user->getRoles();
    $email = $user->getDetail('email');
}

On a path that is not protected the user is the anonymous one (isAnonymous() is true, and its role is anonymous). More in Examples.

Where to go next

On this page

Last updated on 30/10/2026 by Anonymous