跳轉至內容

郵箱驗證

簡介

許多 Web 應用要求使用者在使用應用前驗證其郵箱地址。Laravel 提供了一套便捷的內建服務來發送和驗證郵箱驗證請求,無需您為每個建立的應用手動重複實現此功能。

想要快速開始?在一個全新的 Laravel 應用中安裝 Laravel 應用入門套件。這些入門套件將為您搭建完整的身份驗證系統,包括對郵箱驗證的支援。

模型準備

開始之前,請確保您的 App\Models\User 模型實現了 Illuminate\Contracts\Auth\MustVerifyEmail 契約。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Foundation\Auth\User as Authenticatable;
7use Illuminate\Notifications\Notifiable;
8 
9class User extends Authenticatable implements MustVerifyEmail
10{
11 use Notifiable;
12 
13 // ...
14}

一旦將此介面新增到模型中,新註冊的使用者將自動收到一封包含郵箱驗證連結的郵件。這是因為 Laravel 會自動為 Illuminate\Auth\Events\Registered 事件註冊 Illuminate\Auth\Listeners\SendEmailVerificationNotification 監聽器,從而無縫地完成此過程。

如果您沒有使用 入門套件,而是手動在應用中實現註冊邏輯,則應確保在使用者註冊成功後分發 Illuminate\Auth\Events\Registered 事件。

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

資料庫準備

接下來,您的 users 表必須包含一個 email_verified_at 欄位,用於儲存使用者郵箱地址被驗證的日期和時間。通常情況下,這已包含在 Laravel 預設的 0001_01_01_000000_create_users_table.php 資料庫遷移檔案中。

路由

為了正確實現郵箱驗證,需要定義三個路由。首先,需要一個路由來向用戶顯示通知,告知他們點選 Laravel 在註冊後傳送的驗證郵件中的驗證連結。

其次,需要一個路由來處理使用者點選郵件中驗證連結時生成的請求。

第三,需要一個路由,以便在使用者不慎丟失驗證連結時重新發送驗證連結。

郵箱驗證通知

如前所述,應定義一個路由,該路由返回一個檢視,指導使用者點選 Laravel 在註冊後傳送的驗證連結。當用戶在未驗證郵箱的情況下嘗試訪問應用的其他部分時,將向他們顯示此檢視。請記住,只要您的 App\Models\User 模型實現了 MustVerifyEmail 介面,該連結就會自動傳送給使用者。

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

返回郵箱驗證通知的路由應命名為 verification.notice。為該路由分配此確切名稱非常重要,因為 Laravel 內建的 verified 中介軟體在使用者未驗證郵箱時會自動重定向到此路由名稱。

手動實現郵箱驗證時,您需要自行定義驗證通知檢視的內容。如果您需要包含所有必要身份驗證和驗證檢視的腳手架,請檢視 Laravel 應用入門套件

郵箱驗證處理

接下來,我們需要定義一個路由來處理使用者點選郵件中的驗證連結時觸發的請求。該路由應命名為 verification.verify,並分配 authsigned 中介軟體。

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

在繼續之前,讓我們詳細看一下這個路由。首先,您會注意到我們使用了 EmailVerificationRequest 請求型別,而不是典型的 Illuminate\Http\Request 例項。EmailVerificationRequest 是 Laravel 內建的一個 表單請求。該請求將自動處理對請求 idhash 引數的驗證。

接下來,我們可以直接在請求上呼叫 fulfill 方法。該方法將呼叫已認證使用者的 markEmailAsVerified 方法,並分發 Illuminate\Auth\Events\Verified 事件。markEmailAsVerified 方法透過 Illuminate\Foundation\Auth\User 基類提供給預設的 App\Models\User 模型。一旦使用者的郵箱地址被驗證,您就可以將他們重定向到您希望的任何位置。

重新發送驗證郵件

有時使用者可能會丟失或不小心刪除了郵箱驗證郵件。為了應對這種情況,您可能希望定義一個路由,允許使用者請求重新發送驗證郵件。您可以透過在您的 驗證通知檢視 中放置一個簡單的表單提交按鈕來向該路由傳送請求。

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

保護路由

路由中介軟體 可用於僅允許已驗證的使用者訪問特定路由。Laravel 包含一個 verified 中介軟體別名,它是 Illuminate\Auth\Middleware\EnsureEmailIsVerified 中介軟體類的別名。由於此別名已由 Laravel 自動註冊,您只需將 verified 中介軟體附加到路由定義中即可。通常,此中介軟體會與 auth 中介軟體配合使用。

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

如果未驗證的使用者嘗試訪問分配了此中介軟體的路由,他們將自動被重定向到 verification.notice 命名路由

自定義

驗證郵件自定義

雖然預設的郵箱驗證通知應能滿足大多數應用的需求,但 Laravel 允許您自定義郵件驗證訊息的構建方式。

首先,將閉包傳遞給 Illuminate\Auth\Notifications\VerifyEmail 通知提供的 toMailUsing 方法。該閉包將接收正在接收通知的可通知模型例項以及使用者必須訪問的簽名郵箱驗證 URL。閉包應返回 Illuminate\Notifications\Messages\MailMessage 的例項。通常,您應該在應用 AppServiceProvider 類的 boot 方法中呼叫 toMailUsing 方法。

1use Illuminate\Auth\Notifications\VerifyEmail;
2use Illuminate\Notifications\Messages\MailMessage;
3 
4/**
5 * Bootstrap any application services.
6 */
7public function boot(): void
8{
9 // ...
10 
11 VerifyEmail::toMailUsing(function (object $notifiable, string $url) {
12 return (new MailMessage)
13 ->subject('Verify Email Address')
14 ->line('Click the button below to verify your email address.')
15 ->action('Verify Email Address', $url);
16 });
17}

要了解有關郵件通知的更多資訊,請參閱 郵件通知文件

活動

使用 Laravel 應用入門套件 時,Laravel 會在郵箱驗證過程中分發 Illuminate\Auth\Events\Verified 事件。如果您正在手動為應用處理郵箱驗證,則可能需要在驗證完成後手動分發這些事件。