cyrilbras/email_verification_bundle
Installation:
composer require cyrilbras/email_verification_bundle
Add the bundle to config/bundles.php:
Cyrilbras\EmailVerificationBundle\EmailVerificationBundle::class => ['all' => true],
Publish Config:
php artisan vendor:publish --provider="Cyrilbras\EmailVerificationBundle\EmailVerificationServiceProvider" --tag="config"
Edit config/email_verification.php to configure:
verification_url (e.g., route('email.verify'))expiry_minutes (default: 60)resend_limit (e.g., 3 attempts)mailer (e.g., mail or ses)First Use Case: Trigger verification for a user in a controller:
use Cyrilbras\EmailVerificationBundle\Services\EmailVerificationService;
public function register(Request $request, EmailVerificationService $verifier)
{
$user = User::create($request->validated());
$verifier->sendVerificationEmail($user);
return redirect()->route('home');
}
Verify Route:
Add to routes/web.php:
Route::get('/email/verify/{token}', [EmailVerificationController::class, 'verify'])->name('email.verify');
Sending Verification Emails:
EmailVerificationService to send tokens via:
$verifier->sendVerificationEmail($user, ['custom' => 'data']);
php artisan vendor:publish --tag="email_verification_views"
Override resources/views/vendor/email_verification/email.blade.php.Handling Verification:
verify() method in EmailVerificationController automatically:
is_verified = true).// In EventServiceProvider
protected $listen = [
'Cyrilbras\EmailVerificationBundle\Events\VerificationAttempted' => [
'App\Listeners\LogVerificationAttempt',
],
];
Resending Emails:
Route::post('/email/resend', [EmailVerificationController::class, 'resend'])->name('email.resend');
config/email_verification.php.Token Management:
email_verification_tokens table (auto-created).$verifier->regenerateToken($user);
Laravel Notifications:
Replace the default mailer with a Notification class:
use Cyrilbras\EmailVerificationBundle\Notifications\VerifyEmail;
// In your controller
$user->notify(new VerifyEmail($user));
Multi-Tenant:
Scope tokens to tenants by adding a tenant_id column to the tokens table and filtering queries in the service.
Testing:
Use EmailVerificationService directly in tests:
$verifier->shouldReceive('sendVerificationEmail')->once();
Token Expiry:
expiry_minutes (default: 60). Ensure this aligns with your UX (e.g., shorter for sensitive actions).SELECT * FROM email_verification_tokens WHERE created_at < NOW() - INTERVAL '60 MINUTE';
Database Migrations:
email_verification_tokens table. If you customize the table name in config, run:
php artisan vendor:publish --tag="migrations"
Then modify the published migration.Rate Limiting:
resend_limit config. Bypass cautiously in tests:
$verifier->setResendLimit(10); // Temporarily override
Token Collisions:
User model’s getEmailForVerification() method returns the correct email to avoid mismatches.Log Verification Events:
Listen for VerificationAttempted and VerificationFailed events to debug:
event(new VerificationAttempted($user, $token));
Token Validation: Manually validate a token:
$verifier->validateToken($token); // Returns bool
Email Delivery:
Use Laravel’s Mail::fake() to test emails:
Mail::fake();
$verifier->sendVerificationEmail($user);
Mail::assertSent(VerifyEmail::class);
Custom Token Storage:
Override the TokenRepository interface to use Redis or another store:
$service->setTokenRepository(new RedisTokenRepository());
Dynamic Verification URLs: Customize the verification URL per user:
$verifier->sendVerificationEmail($user, ['url' => route('email.verify', ['tenant' => $tenant])]);
Multi-Factor Verification:
Combine with packages like laravel-fortify by triggering verification after registration:
event(new Registered($user));
$verifier->sendVerificationEmail($user);
Webhook Verification:
Replace the verify() route with a webhook endpoint for API-driven apps:
Route::post('/api/verify', [EmailVerificationController::class, 'webhookVerify']);
How can I help you explore Laravel packages today?