You need to enable JavaScript to run this app. Laravel项目中如何从控制器实现Firebase OTP短信发送功能
优惠活动
大模型
产品
解决方案
定价
更多

Laravel项目中如何从控制器实现Firebase OTP短信发送功能

Laravel 服务端集成Firebase OTP短信验证码实现方案(无前端JS逻辑)

前置依赖安装与配置

  • 首先通过Composer安装Firebase官方PHP Admin SDK:
    composer require kreait/firebase-php
  • 从Firebase控制台下载服务账号JSON凭证文件,放置到项目storage/app/firebase/目录下(目录不存在可自行创建)
  • 在config/services.php中追加Firebase配置项:
'firebase' => [
    'credentials' => storage_path('app/firebase/service-account.json'),
    'project_id' => env('FIREBASE_PROJECT_ID'),
],
  • 在.env文件中补充你的Firebase项目ID:
    FIREBASE_PROJECT_ID=你的Firebase项目ID

路由配置

在routes/web.php中添加两个POST路由,分别对应验证码发送和校验:

// 请求发送OTP验证码
Route::post('/otp/send', [OtpController::class, 'send'])->name('otp.send');
// 校验OTP验证码
Route::post('/otp/verify', [OtpController::class, 'verify'])->name('otp.verify');

生产环境建议给上述路由加throttle限流中间件,避免恶意刷取短信。

控制器逻辑实现

首先执行命令创建控制器:php artisan make:controller OtpController,然后编写对应方法:

发送OTP验证码方法

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Auth;

class OtpController extends Controller
{
    protected $auth;

    public function __construct(Factory $firebase)
    {
        $this->auth = $firebase->createAuth();
    }

    public function send(Request $request)
    {
        // 校验手机号格式,可根据你的业务区域调整规则
        $request->validate([
            'phone' => 'required|string|regex:/^\+?[1-9]\d{1,14}$/'
        ]);

        try {
            // 服务端直接发起手机号验证,无需前端Recaptcha校验
            $verification = $this->auth->startPhoneVerification($request->phone);
            
            // 将验证ID存入Session,*不要返回给前端*,避免泄露篡改
            session(['firebase_verification_id' => $verification->verificationId()]);

            return back()->with('status', '验证码已发送至你的手机');
        } catch (\Exception $e) {
            return back()->withErrors(['phone' => '验证码发送失败:'.$e->getMessage()]);
        }
    }

校验OTP验证码方法

继续在OtpController中追加verify方法:

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

        try {
            // 从Session读取验证ID,和用户提交的验证码做校验
            $verificationId = session('firebase_verification_id');
            if (!$verificationId) {
                throw new \Exception('请先请求发送验证码');
            }

            // 校验验证码有效性
            $verified = $this->auth->verifyPhoneNumber($verificationId, $request->otp_code);

            // 校验通过后清除Session中的验证ID,避免重复使用
            session()->forget('firebase_verification_id');

            // 这里写你的后续业务逻辑,比如用户登录、注册等
            // $verified->phoneNumber() 可以拿到已验证的手机号

            return redirect()->route('dashboard')->with('status', '验证成功');
        } catch (\Exception $e) {
            return back()->withErrors(['otp_code' => '验证码无效或已过期:'.$e->getMessage()]);
        }
    }
}

前端Blade模板示例

完全不需要JavaScript代码,仅用普通表单提交即可:

{{-- 状态提示 --}}
@if(session('status'))
    <div class="alert alert-success">{{ session('status') }}</div>
@endif
@if ($errors->any())
    <div class="alert alert-danger">
        @foreach ($errors->all() as $error)
            <p>{{ $error }}</p>
        @endforeach
    </div>
@endif

{{-- 发送验证码表单 --}}
<form action="{{ route('otp.send') }}" method="POST">
    @csrf
    <div>
        <label>手机号(带国际区号,比如+8613xxxxxxxxx)</label>
        <input type="tel" name="phone" required>
    </div>
    <button type="submit">发送验证码</button>
</form>

{{-- 校验验证码表单 --}}
<form action="{{ route('otp.verify') }}" method="POST" style="margin-top: 20px">
    @csrf
    <div>
        <label>6位验证码</label>
        <input type="text" name="otp_code" required maxlength="6">
    </div>
    <button type="submit">提交验证</button>
</form>

注意事项

  • 手机号需要带国际区号,比如中国手机号格式为+8613xxxxxxxxx,如果需要默认补区号可以在控制器send方法中自行处理
  • Firebase OTP有官方发送频率限制,生产环境建议额外叠加业务层的短信发送频率校验
  • 可以根据需求在发送验证码后加倒计时提示,纯服务端渲染即可,无需JS实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 02:45:04