EmailVerify LogoEmailVerify

Laravel

Email checker for Laravel. PHP email verification in Laravel controllers and forms.

Fügen Sie E-Mail-Verifikation zu Ihrer Laravel-Anwendung hinzu, indem Sie benutzerdefinierte Validierungsregeln, Middleware und Service Provider verwenden.

Installieren

composer require emailverify/laravel

Oder installieren Sie das PHP SDK direkt:

composer require emailverify/php-sdk

Konfiguration

Konfiguration veröffentlichen

php artisan vendor:publish --tag=emailverify-config

Umgebungsvariablen

# .env
EMAILVERIFY_API_KEY=bv_live_xxx

Konfigurationsdatei

// config/emailverify.php
return [
    'api_key' => env('EMAILVERIFY_API_KEY'),
    'timeout' => 10,
    'cache_duration' => 3600, // 1 hour
    'block_disposable' => true,
    'block_role_based' => false,
];

Service Provider

Registrieren Sie den Service Provider, wenn die automatische Registrierung nicht verwendet wird:

// config/app.php
'providers' => [
    EmailVerify\Laravel\EmailVerifyServiceProvider::class,
],

'aliases' => [
    'EmailVerify' => EmailVerify\Laravel\Facades\EmailVerify::class,
],

Validierungsregel

Verwendung der integrierten 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' => 'Please provide a valid email address.',
        ];
    }
}

Benutzerdefinierte Validierungsregel

// 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('The :attribute must be a valid email address.');
                return;
            }

            if ($this->blockDisposable && $result->result->disposable) {
                $fail('Disposable email addresses are not allowed.');
                return;
            }

            if ($this->blockRoleBased && $result->result->role) {
                $fail('Role-based email addresses are not allowed.');
                return;
            }

        } catch (\Exception $e) {
            // Log error but don't block submission
            \Log::warning('EmailVerify API error', [
                'email' => $value,
                'error' => $e->getMessage(),
            ]);
        }
    }
}

Verwendung

use App\Rules\ValidEmail;

$request->validate([
    'email' => ['required', 'email', new ValidEmail(
        blockDisposable: true,
        blockRoleBased: false
    )],
]);

Facade-Verwendung

use EmailVerify\Laravel\Facades\EmailVerify;

// Single verification
$result = EmailVerify::verify('user@example.com');

if ($result->status === 'valid') {
    // Email is valid
}

// Check specific properties
if (EmailVerify::isDisposable('user@example.com')) {
    // Block disposable email
}

if (EmailVerify::isValid('user@example.com')) {
    // Email is deliverable
}

Middleware

Erstellen Sie Middleware für Verifikation auf Routenebene.

Middleware erstellen

// 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' => 'Invalid email address',
                ], 422);
            }

            // Add verification result to request
            $request->merge(['email_verification' => $result]);

        } catch (\Exception $e) {
            \Log::warning('Email verification failed', [
                'email' => $email,
                'error' => $e->getMessage(),
            ]);
        }

        return $next($request);
    }
}

Middleware registrieren

// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'verify.email' => \App\Http\Middleware\VerifyEmailAddress::class,
    ]);
})

// Or in app/Http/Kernel.php (Laravel 10)
protected $middlewareAliases = [
    'verify.email' => \App\Http\Middleware\VerifyEmailAddress::class,
];

In Routes verwenden

Route::post('/register', [AuthController::class, 'register'])
    ->middleware('verify.email');

Route::post('/subscribe', [NewsletterController::class, 'subscribe'])
    ->middleware('verify.email:subscriber_email');

Controller-Integration

// 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',
        ]);

        // Verify email
        $verification = $this->emailVerify->verify($validated['email']);

        if ($verification->status === 'invalid') {
            return back()->withErrors([
                'email' => 'Please provide a valid email address.',
            ]);
        }

        if ($verification->result->disposable) {
            return back()->withErrors([
                'email' => 'Disposable emails are not allowed.',
            ]);
        }

        // Create user
        $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

Zwischenspeichern Sie Verifikationsergebnisse, um API-Aufrufe zu reduzieren.

// 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-Registrierung

// app/Providers/AppServiceProvider.php
public function register(): void
{
    $this->app->singleton(EmailVerificationService::class);
}

Verwendung

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' => 'Invalid email']);
        }

        // Continue processing
    }
}

Massen-Verifikation

Verifizieren Sie mehrere E-Mails effizient.

// 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 = 'Verify all user email addresses';

    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("Verifying {$users->count()} emails...");

        // Submit bulk job
        $emails = $users->pluck('email')->toArray();
        $job = $client->verifyBulk($emails);

        $this->info("Job ID: {$job->job_id}");

        // Poll for completion
        $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();

        // Get results and update users
        $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('Verification complete!');
        $this->table(
            ['Status', 'Count'],
            collect($results->results)
                ->groupBy('status')
                ->map(fn($items, $status) => [$status, $items->count()])
                ->values()
        );
    }
}

Event Listener

Reagieren Sie auf Verifikationsergebnisse mit 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('Invalid email detected', [
                'email' => $event->email,
            ]);
        }

        if ($event->result['disposable'] ?? false) {
            Log::info('Disposable email blocked', [
                'email' => $event->email,
            ]);
        }
    }
}

Testing

Mock the Service (Service mocken)

// 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' => 'John Doe',
            'email' => 'john@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' => 'John Doe',
            'email' => 'temp@mailinator.com',
            'password' => 'password123',
            'password_confirmation' => 'password123',
        ]);

        $response->assertSessionHasErrors('email');
    }
}

Verwandte Ressourcen

On this page