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

Laravel 8中如何将Jetstream邮箱认证改为手机号认证?

嘿,我来一步步带你把Laravel 8 + Jetstream的邮箱认证换成手机号认证,其实整个流程拆解开就很清晰,跟着下面的步骤来就行:

第一步:修改用户表结构

首先得给用户表加上手机号相关的字段,我们需要三个核心字段:存储手机号的phone、标记手机号是否验证的phone_verified_at,还有临时存验证码的verification_token。

  1. 生成迁移文件:
php artisan make:migration add_phone_verification_fields_to_users_table
  1. 打开生成的迁移文件,填入以下代码:
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('phone')->unique()->after('email');
        $table->timestamp('phone_verified_at')->nullable();
        $table->string('verification_token')->nullable();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn(['phone', 'phone_verified_at', 'verification_token']);
    });
}
  1. 运行迁移生效:
php artisan migrate
第二步:调整User模型

接下来要修改User模型,适配手机号验证的逻辑:

  1. 更新$fillable数组,加入新增的字段:
protected $fillable = [
    'name',
    'phone',
    'password',
    'verification_token',
];
  1. 更新$casts数组,把邮箱验证的字段换成手机号的:
protected $casts = [
    'phone_verified_at' => 'datetime',
    'password' => 'hashed',
];
  1. 添加手机号验证相关的方法,替换原来的邮箱验证方法:
// 检查手机号是否已验证
public function hasVerifiedPhone()
{
    return !is_null($this->phone_verified_at);
}

// 标记手机号为已验证
public function markPhoneAsVerified()
{
    return $this->forceFill([
        'phone_verified_at' => $this->freshTimestamp(),
    ])->save();
}

// 发送手机号验证通知
public function sendPhoneVerificationNotification()
{
    // 生成6位随机验证码
    $token = rand(100000, 999999);
    $this->verification_token = $token;
    $this->save();

    $this->notify(new \App\Notifications\VerifyPhone($token));
}
第三步:创建手机号验证通知类

现在需要一个通知类来发送短信验证码,我们用Laravel的通知系统来实现:

  1. 生成通知类:
php artisan make:notification VerifyPhone
  1. 打开app/Notifications/VerifyPhone.php,替换成以下内容(这里以Vonage短信服务商为例,你可以换成自己用的服务商,比如阿里云/腾讯云短信):
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\VonageMessage;
use Illuminate\Notifications\Notification;

class VerifyPhone extends Notification
{
    use Queueable;

    protected $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function via($notifiable)
    {
        return ['vonage']; // 换成你的短信驱动
    }

    public function toVonage($notifiable)
    {
        return (new VonageMessage)
            ->content("你的Laravel账号验证码是:{$this->token},请在5分钟内完成验证。");
    }
}
  1. 在.env文件里配置短信服务商的密钥(以Vonage为例):
VONAGE_KEY=你的Vonage密钥
VONAGE_SECRET=你的Vonage密钥
第四步:修改Jetstream/Fortify的认证逻辑

Jetstream底层用Fortify处理认证,我们需要修改注册、登录的逻辑:

1. 修改注册逻辑

打开app/Actions/Fortify/CreateNewUser.php,把邮箱相关的验证和存储换成手机号:

public function create(array $input)
{
    Validator::make($input, [
        'name' => ['required', 'string', 'max:255'],
        'phone' => ['required', 'string', 'max:20', 'unique:users'],
        'password' => $this->passwordRules(),
    ])->validate();

    $user = User::create([
        'name' => $input['name'],
        'phone' => $input['phone'],
        'password' => Hash::make($input['password']),
    ]);

    // 注册后自动发送验证短信
    $user->sendPhoneVerificationNotification();

    return $user;
}

2. 修改登录逻辑

打开app/Actions/Fortify/AttemptToAuthenticate.php,把登录字段从email换成phone:

protected function attemptLogin($request)
{
    return $this->guard->attempt(
        ['phone' => $request->phone, 'password' => $request->password],
        $request->filled('remember')
    );
}

3. 更新Fortify配置

打开app/Providers/FortifyServiceProvider.php,在boot方法里设置认证字段为手机号:

public function boot()
{
    // ... 保留其他原有代码

    // 自定义认证逻辑,用手机号登录
    Fortify::authenticateUsing(function (Request $request) {
        $user = User::where('phone', $request->phone)->first();

        if ($user && Hash::check($request->password, $user->password)) {
            return $user;
        }
    });
}
第五步:替换认证视图

Jetstream的视图默认在resources/views/auth目录下,我们需要把邮箱相关的输入框换成手机号:

1. 修改注册视图

打开resources/views/auth/register.blade.php,找到邮箱输入框的部分,替换成:

<div>
    <x-label for="phone" value="{{ __('手机号') }}" />
    <x-input id="phone" class="block mt-1 w-full" type="text" name="phone" :value="old('phone')" required autofocus />
</div>

2. 修改登录视图

打开resources/views/auth/login.blade.php,同样替换邮箱输入框:

<div>
    <x-label for="phone" value="{{ __('手机号') }}" />
    <x-input id="phone" class="block mt-1 w-full" type="text" name="phone" :value="old('phone')" required autofocus />
</div>

3. 创建手机号验证页面

新建resources/views/auth/verify-phone.blade.php,用来展示验证码输入表单:

<x-guest-layout>
    <x-authentication-card>
        <x-slot name="logo">
            <x-authentication-card-logo />
        </x-slot>

        <div class="mb-4 text-sm text-gray-600">
            {{ __('感谢注册!请输入我们发送到你手机上的6位验证码完成验证。') }}
        </div>

        @if (session('error'))
            <div class="mb-4 font-medium text-sm text-red-600">
                {{ session('error') }}
            </div>
        @endif

        <x-validation-errors class="mb-4" />

        <form method="POST" action="{{ route('verification.verify') }}">
            @csrf

            <div>
                <x-label for="token" value="{{ __('验证码') }}" />
                <x-input id="token" class="block mt-1 w-full" type="text" name="token" required autofocus />
            </div>

            <div class="flex items-center justify-end mt-4">
                <x-button type="submit" class="ml-4">
                    {{ __('验证') }}
                </x-button>
            </div>
        </form>
    </x-authentication-card>
</x-guest-layout>
第六步:配置验证路由和中间件

1. 添加验证路由

打开routes/web.php,添加手机号验证的路由:

use App\Http\Controllers\Auth\VerificationController;

Route::get('/verify-phone', [VerificationController::class, 'show'])->name('verification.notice');
Route::post('/verify-phone', [VerificationController::class, 'verify'])->name('verification.verify');

2. 创建验证控制器

生成VerificationController处理验证逻辑:

php artisan make:controller Auth/VerificationController

打开app/Http/Controllers/Auth/VerificationController.php,填入以下代码:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;

class VerificationController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function show()
    {
        // 如果已经验证过,直接跳转到仪表盘
        if (auth()->user()->hasVerifiedPhone()) {
            return redirect()->route('dashboard');
        }

        return view('auth.verify-phone');
    }

    public function verify(Request $request)
    {
        $request->validate([
            'token' => 'required|digits:6',
        ]);

        $user = auth()->user();

        // 验证验证码是否匹配
        if ($user->verification_token === $request->token) {
            $user->markPhoneAsVerified();
            $user->verification_token = null;
            $user->save();

            return redirect()->route('dashboard')->with('success', __('手机号验证成功!'));
        }

        return back()->with('error', __('验证码无效,请重新输入。'));
    }
}

3. 替换验证中间件

Laravel默认的verified中间件是检查邮箱验证的,我们需要改成检查手机号:

  1. 复制app/Http/Middleware/EnsureEmailIsVerified.php,重命名为EnsurePhoneIsVerified.php
  2. 修改文件内容:
namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\MustVerifyPhone;
use Illuminate\Http\Request;

class EnsurePhoneIsVerified
{
    public function handle(Request $request, Closure $next, $redirectToRoute = null)
    {
        if (! $request->user() ||
            ($request->user() instanceof MustVerifyPhone &&
            ! $request->user()->hasVerifiedPhone())) {
            return $request->expectsJson()
                ? abort(403, '你的手机号尚未验证。')
                : redirect()->route('verification.notice');
        }

        return $next($request);
    }
}
  1. 打开app/Http/Kernel.php,把verified中间件替换成我们新的:
protected $routeMiddleware = [
    // ... 其他中间件
    'verified' => \App\Http\Middleware\EnsurePhoneIsVerified::class,
];
第七步:测试整个流程

最后,清理一下缓存,然后测试注册、登录、验证的完整流程:

php artisan config:clear
php artisan view:clear

现在你就可以用手机号完成注册、登录和验证了!如果需要调整短信服务商,只需要修改VerifyPhone通知类里的via方法和对应的发送逻辑就行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:02:50