Installation Add the package via Composer:
composer require draw/security
Register the service provider in config/app.php:
'providers' => [
// ...
Draw\Security\SecurityServiceProvider::class,
],
Basic Usage
The package provides a Security facade for common security operations. Import it in your controller or service:
use Draw\Security\Facades\Security;
First Use Case: Password Hashing
Hash a password (compatible with Symfony’s PasswordHasher):
$hashedPassword = Security::hashPassword('plain-text-password');
First Use Case: Password Verification Verify a password against a hash:
$isValid = Security::verifyPassword('plain-text-password', $hashedPassword);
Configuration
Check config/security.php for default settings (e.g., hashing algorithm, cost factors). Override as needed:
'hashing' => [
'algorithm' => 'bcrypt',
'cost' => 12,
],
Authentication
Use the Authenticator class to handle login/logout flows:
// Login
$user = Security::authenticate($credentials);
Security::login($user);
// Logout
Security::logout();
Role-Based Access Control (RBAC)
Define roles in config/security.php:
'roles' => [
'admin' => ['create', 'read', 'update', 'delete'],
'user' => ['read'],
],
Check permissions in controllers:
if (Security::isGranted('ROLE_ADMIN', 'create')) {
// Allow action
}
CSRF Protection Generate and validate tokens in forms:
// Generate token
$token = Security::generateCsrfToken();
// Validate token
if (Security::validateCsrfToken($token)) {
// Proceed
}
Password Reset
Use the PasswordReset helper for secure token generation and validation:
$token = Security::generatePasswordResetToken($user->email);
$isValid = Security::validatePasswordResetToken($token);
Laravel Auth Integration
Extend Laravel’s Authenticatable to use the Security facade for password hashing:
use Draw\Security\Facades\Security;
use Illuminate\Contracts\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmail
{
public function setPasswordAttribute($password)
{
$this->attributes['password'] = Security::hashPassword($password);
}
}
Middleware Create custom middleware for role checks:
namespace App\Http\Middleware;
use Draw\Security\Facades\Security;
use Closure;
class RoleMiddleware
{
public function handle($request, Closure $next, $role)
{
if (!Security::isGranted($role)) {
abort(403);
}
return $next($request);
}
}
Event Listeners
Listen for security events (e.g., auth.attempted, password.reset) via Laravel’s event system:
Security::addListener('auth.attempted', function ($event) {
// Log failed attempts
});
Algorithm Compatibility
bcrypt, but Symfony’s PasswordHasher supports multiple algorithms (e.g., argon2i). Ensure your Laravel app’s App\Providers\AppServiceProvider configures the hasher correctly:
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory;
public function register()
{
$this->app->singleton(UserPasswordHasher::class, function ($app) {
return new UserPasswordHasher(
new PasswordHasherFactory(),
'bcrypt', // or 'argon2i'
['cost' => 12]
);
});
}
Token Storage
session(['csrf_token' => Security::generateCsrfToken()]);
Role Hierarchy
admin > user). Implement this logic in your isGranted checks:
if (Security::isGranted('ROLE_ADMIN') || Security::isGranted('ROLE_USER')) {
// Allow
}
Deprecation Risks
Password Hashing Issues
algorithm and cost in config/security.php match your expectations. Use Symfony’s PasswordHasher directly for debugging:
$hasher = app(UserPasswordHasher::class);
$hash = $hasher->hashPassword($user, 'plain-password');
CSRF Token Mismatches
// app/Http/Middleware/VerifyCsrfToken.php
public function handle($request, Closure $next)
{
if (!Security::validateCsrfToken($request->input('_token'))) {
abort(403);
}
return $next($request);
}
Custom Hashers
Security facade to support additional hashing algorithms:
Security::extendHasher('argon2id', function () {
return new Argon2idHasher();
});
Event System
Security::addListener('auth.failed', function ($event) {
// Trigger analytics
});
Database Backend
TokenManager class:
class DatabaseTokenManager extends TokenManager
{
public function generateToken()
{
$token = parent::generateToken();
DB::table('tokens')->insert(['token' => $token]);
return $token;
}
}
Two-Factor Authentication (2FA)
two-factor package or build custom 2FA logic using the Security facade’s event system.How can I help you explore Laravel packages today?