Authentication
Marko’s authentication system uses a guard-based architecture. Guards handle the “how” of authentication (sessions, tokens, API keys), while user providers handle the “where” (database, LDAP, external API).
composer require marko/authenticationConfigure guards in config/auth.php:
<?php
declare(strict_types=1);
return [ 'defaults' => [ 'guard' => 'web', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'database', ], 'api' => [ 'driver' => 'token', 'provider' => 'database', ], ], 'providers' => [ 'database' => [ 'driver' => 'database', 'table' => 'users', ], ],];Using Authentication
Section titled “Using Authentication”Inject AuthManager to check authentication state:
<?php
declare(strict_types=1);
namespace App\Dashboard\Controller;
use Marko\Authentication\AuthManager;use Marko\Routing\Attributes\Get;use Marko\Routing\Attributes\Middleware;use Marko\Authentication\Middleware\AuthMiddleware;use Marko\Http\ResponseInterface;use Marko\Http\JsonResponse;
class DashboardController{ public function __construct( private readonly AuthManager $authManager, ) {}
#[Get('/dashboard')] #[Middleware(AuthMiddleware::class)] public function index(): ResponseInterface { $user = $this->authManager->user();
return new JsonResponse(data: [ 'message' => "Welcome, {$user->name}", ]); }}Guards
Section titled “Guards”Session Guard
Section titled “Session Guard”For traditional web applications with cookie-based sessions:
// Login$this->auth->guard('web')->attempt([ 'email' => $email, 'password' => $password,]);
// Check if authenticated$this->auth->guard('web')->check(); // bool
// Get the authenticated user$this->auth->guard('web')->user(); // AuthenticatableInterface|null
// Logout$this->auth->guard('web')->logout();Token Guard
Section titled “Token Guard”For APIs using bearer tokens:
// Authenticate from the request's Authorization header$this->auth->guard('api')->user();Middleware
Section titled “Middleware”Marko provides two authentication middleware classes:
use Marko\Authentication\Middleware\AuthMiddleware; // Must be logged inuse Marko\Authentication\Middleware\GuestMiddleware; // Must NOT be logged in
#[Get('/dashboard')]#[Middleware(AuthMiddleware::class)]public function dashboard(): ResponseInterface { /* ... */ }
#[Get('/login')]#[Middleware(GuestMiddleware::class)]public function loginForm(): ResponseInterface { /* ... */ }Custom Guard
Section titled “Custom Guard”Create your own authentication strategy by implementing GuardInterface:
<?php
declare(strict_types=1);
namespace App\MyApp\Auth;
use Marko\Authentication\Contracts\GuardInterface;use Marko\Authentication\AuthenticatableInterface;
class ApiKeyGuard implements GuardInterface{ public function check(): bool { return $this->user() !== null; }
public function guest(): bool { return !$this->check(); }
public function user(): ?AuthenticatableInterface { // Look up user by API key from request header }
public function id(): int|string|null { return $this->user()?->getAuthIdentifier(); }
public function attempt(array $credentials): bool { // Validate API key credentials }
public function login(AuthenticatableInterface $user): void { // Store the authenticated user }
public function loginById(int|string $id): ?AuthenticatableInterface { // Find and log in a user by ID }
public function logout(): void { // Invalidate the API key }
public function getName(): string { return 'api-key'; }}Register it via Preference in your module.php:
use Marko\Authentication\Contracts\GuardInterface;use App\MyApp\Auth\ApiKeyGuard;
return [ 'bindings' => [ GuardInterface::class => ApiKeyGuard::class, ],];Events
Section titled “Events”The authentication system dispatches events you can observe:
| Event | When |
|---|---|
LoginEvent | Successful login |
LogoutEvent | User logs out |
FailedLoginEvent | Login attempt fails |
PasswordResetEvent | Password is reset |
use Marko\Authentication\Event\FailedLoginEvent;use App\Security\Observer\LockoutAfterFailures;
return [ 'observers' => [ FailedLoginEvent::class => [ LockoutAfterFailures::class, ], ],];Next Steps
Section titled “Next Steps”- Routing — protect routes with middleware
- Authorization — role-based access control
- Testing — test authentication flows
- Authentication package reference — full API details