You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel API路由中实现用户注册后的邮箱验证功能

Laravel API 场景下邮箱验证实现方案

你的现有代码已经满足基础前置条件:User 模型已实现 MustVerifyEmail 接口,且数据表包含 email_verified_at 字段,只需按以下步骤调整即可:

1. 调整注册逻辑,触发验证邮件

在 AuthController 的 register 方法中,用户创建完成后添加发送验证邮件的逻辑,同时自定义验证链接跳转至你的 Angular 前端地址:
首先修改 app/Providers/AppServiceProvider.php 的 boot 方法,自定义验证链接生成规则:

<?php

namespace App\Providers;

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        VerifyEmail::createUrlUsing(function ($notifiable) {
            // 此处替换为你的Angular前端验证页面地址
            $frontendUrl = env('FRONTEND_URL', 'http://localhost:4200') . '/verify-email';
            // 生成Laravel签名URL参数
            $verifyUrl = \URL::temporarySignedRoute(
                'verification.verify',
                \Illuminate\Support\Facades\Config::get('auth.verification.expire', 60),
                [
                    'id' => $notifiable->getKey(),
                    'hash' => sha1($notifiable->getEmailForVerification()),
                ]
            );
            // 把签名参数拼到前端地址上
            return $frontendUrl . '?' . parse_url($verifyUrl, PHP_URL_QUERY);
        });
    }
}

然后修改 AuthController 的 register 方法,添加发送邮件逻辑:

public function register(Request $request) {
    $validator = Validator::make($request->all(), [
        'name' => 'required|string|between:2,100',
        'email' => 'required|string|email|max:100|unique:users',
        'password' => 'required|string|confirmed|min:6',
    ]);

    if($validator->fails()){
        return response()->json($validator->errors(), 422);
    }

    $user = User::create(array_merge(
                $validator->validated(),
                ['password' => bcrypt($request->password)]
            ));
    // 新增:发送邮箱验证邮件
    $user->sendEmailVerificationNotification();
    
    return response()->json([
        'message' => 'User successfully registered, please check your email for verification link',
        'user' => $user
    ], 201);
}

2. 新增邮箱验证相关接口

在 AuthController 中添加验证邮箱、重发验证邮件两个方法:

use Illuminate\Auth\Events\Verified;
use Illuminate\Support\Facades\URL;

// 验证邮箱
public function verify(Request $request)
{
    $user = User::findOrFail($request->route('id'));

    if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
        return response()->json(['message' => 'Invalid verification link'], 403);
    }

    if ($user->hasVerifiedEmail()) {
        return response()->json(['message' => 'Email already verified'], 200);
    }

    if ($user->markEmailAsVerified()) {
        event(new Verified($user));
    }

    return response()->json(['message' => 'Email verified successfully'], 200);
}

// 重发验证邮件
public function resend(Request $request)
{
    if ($request->user()->hasVerifiedEmail()) {
        return response()->json(['message' => 'Email already verified'], 400);
    }

    $request->user()->sendEmailVerificationNotification();

    return response()->json(['message' => 'Verification link sent']);
}

3. 调整登录逻辑,增加邮箱验证校验

修改 login 方法,未验证邮箱的用户不允许登录:

public function login(Request $request){
    $validator = Validator::make($request->all(), [
        'email' => 'required|email',
        'password' => 'required|string|min:6',
    ]);

    if ($validator->fails()) {
        return response()->json($validator->errors(), 422);
    }

    // 新增:校验用户是否已验证邮箱
    if (!auth()->validate($validator->validated())) {
        return response()->json(['error_message' => 'Invalid Credentials'], 401);
    }
    $user = auth()->getLastAttempted();
    if (!$user->hasVerifiedEmail()) {
        return response()->json(['error_message' => 'Please verify your email first'], 403);
    }

    $token = auth()->login($user);
    return $this->createNewToken($token);
}

4. 新增API路由

在 routes/api.php 中添加以下路由:

Route::get('/email/verify/{id}/{hash}', [AuthController::class, 'verify'])->middleware(['signed', 'throttle:6,1'])->name('verification.verify');
Route::post('/email/resend', [AuthController::class, 'resend'])->middleware(['auth:api', 'throttle:6,1'])->name('verification.send');

5. Angular前端适配

  • 用户点击邮件内的验证链接会跳转至你的Angular验证页面,从页面URL中提取所有查询参数(expires、signature、id、hash),直接拼接在后端 /api/email/verify/{id}/{hash} 接口后发起GET请求即可完成验证
  • 若验证链接过期,可提供重发按钮,携带用户登录返回的JWT token调用 /api/email/resend 接口重新发送验证邮件

注意:请提前在.env文件中配置好邮件发送相关参数,确保Laravel可以正常发送邮件。

内容的提问来源于stack exchange,提问作者user3653474

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:06:03