Installation
Add via Composer (Laravel already includes Symfony Security components via laravel/framework):
composer require symfony/security-bundle
(Note: Laravel’s built-in auth scaffolding uses Symfony Security under the hood, so this is often pre-configured.)
First Use Case: Basic Authentication
auth() helper or Auth facade to check authentication:
if (auth()->check()) {
$user = auth()->user();
}
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
Where to Look First
app/Http/Middleware/Authenticate.php: Core middleware leveraging Symfony’s AuthenticationProviderManager.Auth facade uses Symfony’s Guard system. Extend guards for custom logic:
// app/Providers/AuthServiceProvider.php
protected function guards()
{
return [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token', // Uses Symfony’s TokenGuard
'provider' => 'users',
],
];
}
Symfony\Component\Security\Core\User\UserProviderInterface:
class CustomUserProvider implements UserProviderInterface {
public function loadUserByIdentifier($identifier) {
return User::where('email', $identifier)->firstOrFail();
}
// ... other required methods
}
Voter interface for granular permissions:
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class PostVoter extends Voter {
protected function supports(string $attribute, $subject): bool {
return $attribute === 'EDIT';
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool {
return $token->getUser()->id === $subject->user_id;
}
}
// app/Providers/AuthServiceProvider.php
protected $policies = [
Post::class => PostPolicy::class,
];
(Laravel’s Policy class extends Symfony’s Voter.)SessionAuthenticationStrategyInterface for stateless APIs or custom session handling.form_login, http_basic) in Laravel’s app/Http/Kernel.php or via middleware.@csrf directive uses Symfony’s CsrfTokenManager. Override token generation in app/Providers/AppServiceProvider:
public function register()
{
$this->app->singleton(Symfony\Component\Security\Csrf\CsrfTokenManagerInterface::class, function () {
return new CustomCsrfTokenManager();
});
}
InteractiveLoginEvent, AuthenticationSuccessEvent) via Laravel’s event system:
// app/Listeners/LogSuccessfulLogin.php
public function handle(AuthenticationSuccessEvent $event) {
Log::info('User logged in', ['user' => $event->getUser()]);
}
Register in EventServiceProvider.Session Fixation
session.regenerate() is called after login (Laravel’s AuthenticatesUsers trait handles this by default).AlwaysStoreSessionInterface can help enforce this.Token Expiry in Stateless APIs
User model:
public function tokens()
{
return $this->hasMany(Spatie\LaravelPermission\Models\Token::class);
}
TokenStorage to clear tokens on logout.Circular Dependencies in Voters
Voter::vote(). Cache results or use DTOs.Middleware Order Matters
auth middleware before throttle or custom middleware that might short-circuit requests.Enable Symfony’s Security Debug Tool:
// config/app.php
'providers' => [
Symfony\Bundle\DebugBundle\DebugBundle::class,
],
(Adds a security tab in Laravel Debugbar.)
Log Authentication Events:
// config/logging.php
'channels' => [
'security' => [
'driver' => 'single',
'path' => storage_path('logs/security.log'),
'level' => 'debug',
],
],
Then log events in listeners.
Dump Token Data:
dd(auth()->user(), auth()->token(), auth()->getLastAttempted());
Custom Authentication Providers
Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface for OAuth, LDAP, or custom backends.Firewall Layers
main, api) in app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Symfony\Component\Security\Http\Firewall::class, // Symfony Firewall
],
];
Password Reset with Symfony’s UserCheckerInterface
Symfony\Component\Security\Core\User\UserChecker to validate users before password changes:
class CustomUserChecker implements UserCheckerInterface {
public function checkPreAuth(UserInterface $user) {
if (!$user->isActive()) {
throw new DisabledException('User account is disabled.');
}
}
}
Two-Factor Authentication (2FA)
TwoFactorAuthenticatorInterface or integrate with Laravel’s laravel-2fa package (which uses Symfony’s components).file/database session drivers work with Symfony Security, but redis requires additional config:
// config/session.php
'driver' => 'redis',
'connection' => 'cache',
SESSION_DOMAIN in .env to match Symfony’s SameSite cookie policies:
SESSION_DOMAIN=.yourdomain.com
Symfony\Component\Security\Core\User\UserProviderInterface::refreshUser() to avoid loading users unnecessarily.class CachedVoterDecorator implements VoterInterface {
private $decorated;
private $cache;
public function vote(TokenInterface $token, $object, array $attributes) {
$cacheKey = md5($token->getUser().serialize($object).$attributes[0]);
if ($this->cache->has($cacheKey)) {
return $this->cache->get($cacheKey);
}
$result = $this->decorated->vote($token, $object, $attributes);
$this->cache->put($cacheKey, $result, 3600);
return $result;
}
}
How can I help you explore Laravel packages today?