Laravel
Email checker for Laravel. PHP email verification in Laravel controllers and forms.
Voeg e-mailverificatie toe aan uw Laravel applicatie met aangepaste validatieregels, middleware en service providers.
Installatie
composer require emailverify/laravelOf installeer de PHP SDK direct:
composer require emailverify/php-sdkConfiguratie
Publiceer Configuratie
php artisan vendor:publish --tag=emailverify-configOmgevingsvariabelen
# .env
EMAILVERIFY_API_KEY=bv_live_xxxConfiguratiebestand
// config/emailverify.php
return [
'api_key' => env('EMAILVERIFY_API_KEY'),
'timeout' => 10,
'cache_duration' => 3600, // 1 uur
'block_disposable' => true,
'block_role_based' => false,
];Service Provider
Registreer de service provider als auto-discovery niet wordt gebruikt:
// config/app.php
'providers' => [
EmailVerify\Laravel\EmailVerifyServiceProvider::class,
],
'aliases' => [
'EmailVerify' => EmailVerify\Laravel\Facades\EmailVerify::class,
],Validatieregel
Gebruik van de Ingebouwde Regel
use App\Http\Requests\RegisterRequest;
class RegisterRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => ['required', 'email', 'emailverify'],
'name' => ['required', 'string', 'max:255'],
'password' => ['required', 'confirmed', 'min:8'],
];
}
public function messages(): array
{
return [
'email.emailverify' => 'Geef een geldig e-mailadres op.',
];
}
}Aangepaste Validatieregel
// app/Rules/ValidEmail.php
<?php
namespace App\Rules;
use EmailVerify\Client;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class ValidEmail implements ValidationRule
{
protected bool $blockDisposable;
protected bool $blockRoleBased;
public function __construct(
bool $blockDisposable = true,
bool $blockRoleBased = false
) {
$this->blockDisposable = $blockDisposable;
$this->blockRoleBased = $blockRoleBased;
}
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$client = new Client(config('emailverify.api_key'));
try {
$result = $client->verify($value);
if ($result->status === 'invalid') {
$fail('Het :attribute moet een geldig e-mailadres zijn.');
return;
}
if ($this->blockDisposable && $result->result->disposable) {
$fail('Wegwerp e-mailadressen zijn niet toegestaan.');
return;
}
if ($this->blockRoleBased && $result->result->role) {
$fail('Rolgebaseerde e-mailadressen zijn niet toegestaan.');
return;
}
} catch (\Exception $e) {
// Log fout maar blokkeer inzending niet
\Log::warning('EmailVerify API fout', [
'email' => $value,
'error' => $e->getMessage(),
]);
}
}
}Gebruik
use App\Rules\ValidEmail;
$request->validate([
'email' => ['required', 'email', new ValidEmail(
blockDisposable: true,
blockRoleBased: false
)],
]);Facade Gebruik
use EmailVerify\Laravel\Facades\EmailVerify;
// Enkele verificatie
$result = EmailVerify::verify('user@example.com');
if ($result->status === 'valid') {
// E-mail is geldig
}
// Controleer specifieke eigenschappen
if (EmailVerify::isDisposable('user@example.com')) {
// Blokkeer wegwerp e-mail
}
if (EmailVerify::isValid('user@example.com')) {
// E-mail is afleverbaar
}Middleware
Maak middleware voor route-niveau verificatie.
Maak Middleware
// app/Http/Middleware/VerifyEmailAddress.php
<?php
namespace App\Http\Middleware;
use EmailVerify\Client;
use Closure;
use Illuminate\Http\Request;
class VerifyEmailAddress
{
protected Client $client;
public function __construct()
{
$this->client = new Client(config('emailverify.api_key'));
}
public function handle(Request $request, Closure $next, string $field = 'email')
{
$email = $request->input($field);
if (!$email) {
return $next($request);
}
try {
$result = $this->client->verify($email);
if ($result->status === 'invalid') {
return response()->json([
'error' => 'Ongeldig e-mailadres',
], 422);
}
// Voeg verificatieresultaat toe aan verzoek
$request->merge(['email_verification' => $result]);
} catch (\Exception $e) {
\Log::warning('E-mailverificatie mislukt', [
'email' => $email,
'error' => $e->getMessage(),
]);
}
return $next($request);
}
}Registreer Middleware
// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'verify.email' => \App\Http\Middleware\VerifyEmailAddress::class,
]);
})
// Of in app/Http/Kernel.php (Laravel 10)
protected $middlewareAliases = [
'verify.email' => \App\Http\Middleware\VerifyEmailAddress::class,
];Gebruik in Routes
Route::post('/register', [AuthController::class, 'register'])
->middleware('verify.email');
Route::post('/subscribe', [NewsletterController::class, 'subscribe'])
->middleware('verify.email:subscriber_email');Controller Integratie
// app/Http/Controllers/AuthController.php
<?php
namespace App\Http\Controllers;
use App\Models\User;
use EmailVerify\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
protected Client $emailVerify;
public function __construct()
{
$this->emailVerify = new Client(config('emailverify.api_key'));
}
public function register(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|confirmed|min:8',
]);
// Verifieer e-mail
$verification = $this->emailVerify->verify($validated['email']);
if ($verification->status === 'invalid') {
return back()->withErrors([
'email' => 'Geef een geldig e-mailadres op.',
]);
}
if ($verification->result->disposable) {
return back()->withErrors([
'email' => 'Wegwerp e-mails zijn niet toegestaan.',
]);
}
// Maak gebruiker
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
'email_verified_score' => $verification->score,
]);
auth()->login($user);
return redirect('/dashboard');
}
}Caching
Cache verificatieresultaten om API-aanroepen te verminderen.
// app/Services/EmailVerificationService.php
<?php
namespace App\Services;
use EmailVerify\Client;
use Illuminate\Support\Facades\Cache;
class EmailVerificationService
{
protected Client $client;
protected int $cacheDuration;
public function __construct()
{
$this->client = new Client(config('emailverify.api_key'));
$this->cacheDuration = config('emailverify.cache_duration', 3600);
}
public function verify(string $email): object
{
$cacheKey = 'email_verification:' . md5($email);
return Cache::remember($cacheKey, $this->cacheDuration, function () use ($email) {
return $this->client->verify($email);
});
}
public function isValid(string $email): bool
{
return $this->verify($email)->status === 'valid';
}
public function isDisposable(string $email): bool
{
return $this->verify($email)->result->disposable ?? false;
}
public function clearCache(string $email): void
{
Cache::forget('email_verification:' . md5($email));
}
}Service Provider Registratie
// app/Providers/AppServiceProvider.php
public function register(): void
{
$this->app->singleton(EmailVerificationService::class);
}Gebruik
use App\Services\EmailVerificationService;
class SomeController extends Controller
{
public function __construct(
protected EmailVerificationService $emailVerification
) {}
public function store(Request $request)
{
if (!$this->emailVerification->isValid($request->email)) {
return back()->withErrors(['email' => 'Ongeldige e-mail']);
}
// Ga verder met verwerking
}
}Bulk Verificatie
Verifieer meerdere e-mails efficient.
// app/Console/Commands/VerifyUserEmails.php
<?php
namespace App\Console\Commands;
use App\Models\User;
use EmailVerify\Client;
use Illuminate\Console\Command;
class VerifyUserEmails extends Command
{
protected $signature = 'users:verify-emails {--chunk=100}';
protected $description = 'Verifieer alle e-mailadressen van gebruikers';
public function handle()
{
$client = new Client(config('emailverify.api_key'));
$chunk = (int) $this->option('chunk');
$users = User::whereNull('email_verified_at')
->orWhere('email_verification_date', '<', now()->subMonths(3))
->get();
$this->info("Verifieren van {$users->count()} e-mails...");
// Dien bulk taak in
$emails = $users->pluck('email')->toArray();
$job = $client->verifyBulk($emails);
$this->info("Taak ID: {$job->job_id}");
// Poll voor voltooiing
$bar = $this->output->createProgressBar(100);
do {
sleep(5);
$status = $client->getBulkJobStatus($job->job_id);
$bar->setProgress($status->progress_percent);
} while ($status->status !== 'completed');
$bar->finish();
$this->newLine();
// Haal resultaten op en werk gebruikers bij
$results = $client->getBulkJobResults($job->job_id);
foreach ($results->results as $result) {
User::where('email', $result->email)->update([
'email_verification_status' => $result->status,
'email_verification_score' => $result->score,
'email_verification_date' => now(),
]);
}
$this->info('Verificatie voltooid!');
$this->table(
['Status', 'Aantal'],
collect($results->results)
->groupBy('status')
->map(fn($items, $status) => [$status, $items->count()])
->values()
);
}
}Event Listeners
Reageer op verificatieresultaten met events.
// app/Events/EmailVerified.php
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
class EmailVerified
{
use Dispatchable;
public function __construct(
public string $email,
public string $status,
public float $score,
public array $result
) {}
}
// app/Listeners/HandleEmailVerification.php
<?php
namespace App\Listeners;
use App\Events\EmailVerified;
use Illuminate\Support\Facades\Log;
class HandleEmailVerification
{
public function handle(EmailVerified $event): void
{
if ($event->status === 'invalid') {
Log::warning('Ongeldige e-mail gedetecteerd', [
'email' => $event->email,
]);
}
if ($event->result['disposable'] ?? false) {
Log::info('Wegwerp e-mail geblokkeerd', [
'email' => $event->email,
]);
}
}
}Testen
Mock de Service
// tests/Feature/RegistrationTest.php
<?php
namespace Tests\Feature;
use EmailVerify\Client;
use Mockery;
use Tests\TestCase;
class RegistrationTest extends TestCase
{
public function test_registration_with_valid_email(): void
{
$mock = Mockery::mock(Client::class);
$mock->shouldReceive('verify')
->once()
->andReturn((object) [
'status' => 'valid',
'score' => 0.95,
'result' => (object) [
'disposable' => false,
'role' => false,
],
]);
$this->app->instance(Client::class, $mock);
$response = $this->post('/register', [
'name' => 'Jan Jansen',
'email' => 'jan@example.com',
'password' => 'password123',
'password_confirmation' => 'password123',
]);
$response->assertRedirect('/dashboard');
}
public function test_registration_blocks_disposable_email(): void
{
$mock = Mockery::mock(Client::class);
$mock->shouldReceive('verify')
->once()
->andReturn((object) [
'status' => 'valid',
'score' => 0.5,
'result' => (object) [
'disposable' => true,
'role' => false,
],
]);
$this->app->instance(Client::class, $mock);
$response = $this->post('/register', [
'name' => 'Jan Jansen',
'email' => 'temp@mailinator.com',
'password' => 'password123',
'password_confirmation' => 'password123',
]);
$response->assertSessionHasErrors('email');
}
}