Học Laravel – Bài 35: Email Verification

Giới thiệu Email Verification trong Laravel

Nhiều ứng dụng yêu cầu xác minh email. Laravel cung cấp sẵn dịch vụ để gửi và xác minh email. Bạn có thể sử dụng Starter kits.

Chuẩn bị model:

Đầu tiên model User cần implement contract Illuminate\Contracts\Auth\MustVerifyEmail:

<?php
 
namespace App\Models;
 
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
 
    // ...
}

Một khi interface này được thêm vào model, user mới đăng ký sẽ tự động gửi 1 email chứa link xác nhận. Bạn có thể xem ở App\Providers\EventServiceProvider, Laravel đã có 1 listener là SendEmailVerificationNotification được gắn vào event Illuminate\Auth\Events\Registered. Event listener này sẽ gửi link verify đến user.

Nếu bạn code bằng tay thay vì sử dụng starter kits, bạn nên chắc chắn đã kích hoạt sự kiện Registered sau khi user đăng ký thành công:

use Illuminate\Auth\Events\Registered;
 
event(new Registered($user));

Lưu ý nữa là database users phải có trường email_verified_at (Laravel cũng đã có sẵn trong migration).

Routing:

Để thực thi đúng cách, có 3 routes cần được defined. Đầu tiên 1 route cần thiết để hiển thị 1 thông báo đến user rằng họ cần click link email verify. Thứ hai là cần route để xử lý request khi user click. Thứ 3 là route để gửi lại verification link nếu user làm mất link đầu tiên.

Thông báo Email Verification:

Như đề cập trên, cần tạo 1 route để trả về 1 view hướng dẫn người dùng click vào link xác nhận (đã gửi về email – Laravel tự động gửi mail khi model User implement MustVerifyEmail interface):

Route::get('/email/verify', function () {
    return view('auth.verify-email');
})->middleware('auth')->name('verification.notice');

Route trên nên đặt tên là verification.notice. Điều này quan trọng vì middleware verified sẽ tự động redirect đến tên route này nếu user chưa xác minh email.

Lưu ý: khi tự code bằng tay, bạn cần define view thông báo này. Hoặc không, sử dụng starter kits.

Email Verification Handler:

Tiếp theo chúng ta cần define 1 route để xử lý request khi user click vào link xác nhận. Route này nên đặt tên là verification.verify và sẽ được gán cho authsigned middleware:

use Illuminate\Foundation\Auth\EmailVerificationRequest;
 
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
    $request->fulfill();
 
    return redirect('/home');
})->middleware(['auth', 'signed'])->name('verification.verify');

Ở đây lưu ý, ta sử dụng EmailVerificationRequest thay vì Illuminate\Http\Request như thông thường. EmailVerificationRequest là 1 form request có sẵn của Laravel. Request này tự động xử lý tham số idhash của request.

Tiếp theo, bạn có thể gọi method fulfill, method này sẽ gọi method markEmailAsVerified và kích hoạt event Illuminate\Auth\Events\Verified. Sau khi đã verified, bạn redirect user đến link bạn muốn.

Gửi lại Verification Email:

Define 1 route cho phép user request để gửi lại email. Sau đó tạo 1 form request đến route này (form này để ở trong view verification notice được nói trên):

use Illuminate\Http\Request;
 
Route::post('/email/verification-notification', function (Request $request) {
    $request->user()->sendEmailVerificationNotification();
 
    return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');

Protecting Routes:

Route middleware có thể dùng để chỉ cho phép user đã xác minh email mới được tiếp cận. Đó là middleware verified, là alias của class Illuminate\Auth\Middleware\EnsureEmailIsVerified. Middleware này đã được đăng ký ở kernel, nên bạn chỉ cần gán vào route cần bảo vệ. Thông thường middleware này đi kèm với auth middleware:

Route::get('/profile', function () {
    // Only verified users may access this route...
})->middleware(['auth', 'verified']);

Nếu 1 user chưa xác minh cố tiếp cận route này, sẽ được redirect đến verification.notice route.

Tùy biến Email Verification:

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
 
/**
 * Register any authentication / authorization services.
 */
public function boot(): void
{
    // ...
 
    VerifyEmail::toMailUsing(function (object $notifiable, string $url) {
        return (new MailMessage)
            ->subject('Verify Email Address')
            ->line('Click the button below to verify your email address.')
            ->action('Verify Email Address', $url);
    });
}

Events:

Khi sử dụng starter kits, Laravel kích hoạt các event trong quá trình email verification. Nếu bạn tự code, bạn có thể cần kích hoạt bằng tay những event này sau khi verification hoàn thành. Bạn có thể gán listener vào những event này trong EventServiceProvider:

use App\Listeners\LogVerifiedUser;
use Illuminate\Auth\Events\Verified;
 
/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    Verified::class => [
        LogVerifiedUser::class,
    ],
];

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *