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

如何使用PHP/Laravel后端通过API校验Firebase OTP

解决方案:Laravel/PHP 后端对接 Firebase OTP 校验流程

首先明确核心误区:Firebase 不会向客户端、第三方服务暴露其生成的明文OTP内容,你不需要、也无法直接获取Firebase生成的OTP存入自有数据库,自行抓短信内容存OTP的方案既违反Firebase服务规则,也存在验证码泄露、爆破的安全风险。正确的实现逻辑是通过Firebase签发的合法身份凭证完成后端校验,不需要自行存储OTP。


第一步:调整Flutter端交互逻辑

  • 客户端触发Firebase OTP发送、用户输入验证码完成Firebase本地校验后,不要上传用户输入的明文验证码,而是获取Firebase签发的idToken传给后端做合法性校验。
  • Flutter端核心代码示例:
// 用户输入验证码后生成凭证
PhoneAuthCredential credential = PhoneAuthProvider.credential(
  verificationId: _verificationId,
  smsCode: userInputOtp
);
// 完成Firebase侧本地校验
final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
// 拿到校验通过后签发的ID Token
final String? firebaseIdToken = await userCredential.user?.getIdToken();
// 调用自有后端校验接口
final resp = await dio.post('/api/verify-firebase-otp', data: {
  "phone": phoneNumber,
  "firebase_id_token": firebaseIdToken
});
  • 如果需要记录OTP发送日志,可在触发发送动作时单独调用后端接口,仅记录「某手机号于某时间触发验证码发送」即可,不需要记录验证码内容。

第二步:Laravel侧配置Firebase连接

  • 项目内安装Firebase Admin SDK依赖:
composer require kreait/laravel-firebase
  • 执行配置发布命令,将Firebase后台下载的服务账号密钥文件放到项目安全目录,在.env中添加配置:
FIREBASE_CREDENTIALS=storage/secure/firebase-service-account.json
FIREBASE_PROJECT_ID=你的Firebase项目ID

注意:服务账号密钥文件不要提交到公共代码仓库,设置文件权限为仅服务端运行用户可读。

第三步:编写后端校验API

  • 在routes/api.php中定义路由:
Route::post('/verify-firebase-otp', [AuthController::class, 'verifyFirebaseOtp']);
  • 控制器核心校验逻辑,OTP有效性校验完全交给Firebase SDK完成,不需要做本地OTP比对:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Kreait\Firebase\Contract\Auth as FirebaseAuth;
use App\Models\User;

class AuthController extends Controller
{
    public function __construct(protected FirebaseAuth $firebaseAuth)
    {}

    public function verifyFirebaseOtp(Request $request)
    {
        $request->validate([
            'phone' => 'required|string',
            'firebase_id_token' => 'required|string'
        ]);

        try {
            // 校验ID Token合法性、是否在有效期内
            $verifiedToken = $this->firebaseAuth->verifyIdToken($request->firebase_id_token);
            $firebaseUid = $verifiedToken->claims()->get('sub');
            $bindPhone = $verifiedToken->claims()->get('phone_number');

            // 校验Token绑定的手机号和前端上报手机号一致,防止参数伪造
            if ($bindPhone !== $request->phone) {
                return response()->json(['code' => 400, 'msg' => '手机号信息不匹配'], 400);
            }

            // 校验通过后执行自有业务逻辑:创建/更新用户信息、签发自有登录态
            $user = User::firstOrCreate(
                ['phone' => $request->phone],
                ['firebase_uid' => $firebaseUid]
            );
            $authToken = $user->createToken('app_login')->plainTextToken;

            return response()->json([
                'code' => 0,
                'msg' => '校验成功',
                'data' => ['auth_token' => $authToken]
            ]);
        } catch (\Exception $e) {
            // Token过期、伪造、已作废都会进入异常分支
            return response()->json(['code' => 401, 'msg' => '验证码无效或已过期,请重新获取'], 401);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:48:21