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

如何集成Firebase手机认证与Django后端实现用户同步及API鉴权

实现方案

首先提前安装所需依赖:

pip install djangorestframework firebase-admin

需求1:Firebase注册自动同步Django用户

  • 第一步:改造Django用户模型,以Firebase UID作为用户唯一标识,同时新增你需要的扩展字段。你可以直接扩展Django自带的AbstractUser,也可以用一对一关联的独立用户资料表,以下是直接扩展的示例:
# 你的应用/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    firebase_uid = models.CharField(max_length=128, unique=True, null=False, blank=False)
    avatar_url = models.URLField(blank=True)
    address = models.TextField(blank=True)
    # 其他需要的扩展字段(订单、支付记录建议单独建表关联用户)

修改完成后在settings.py中指定自定义用户模型,再执行python manage.py makemigrations和python manage.py migrate完成数据库迁移:

# settings.py
AUTH_USER_MODEL = '你的应用名.CustomUser'
  • 第二步:编写用户同步接口,接口内部先校验Firebase凭证合法性,再同步创建或更新用户:
# 你的应用/views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from firebase_admin import auth
from .models import CustomUser

class SyncFirebaseUserView(APIView):
    permission_classes = [AllowAny]
    def post(self, request):
        id_token = request.data.get("id_token")
        # 校验Firebase凭证合法性,防止恶意调用
        try:
            decoded_token = auth.verify_id_token(id_token)
            firebase_uid = decoded_token["uid"]
            email = decoded_token.get("email", "")
            display_name = decoded_token.get("name", "")
        except Exception as e:
            return Response({"error": "无效的认证凭证"}, status=status.HTTP_401_UNAUTHORIZED)
        
        # 同步用户,已存在的用户直接返回信息不重复创建
        user, created = CustomUser.objects.get_or_create(
            firebase_uid=firebase_uid,
            defaults={
                "email": email,
                "username": firebase_uid,
                "first_name": display_name
            }
        )
        return Response({"user_id": user.id, "firebase_uid": firebase_uid}, status=status.HTTP_200_OK)

记得把这个接口加到路由配置里。

  • 第三步:Flutter端用户完成Firebase注册后,立刻调用上述同步接口:
// Flutter 注册成功后调用示例
import 'package:firebase_auth/firebase_auth.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> syncUserToDjango() async {
  User? currentUser = FirebaseAuth.instance.currentUser;
  if (currentUser != null) {
    String? idToken = await currentUser.getIdToken();
    await http.post(
      Uri.parse("你的Django服务地址/api/sync-firebase-user/"),
      headers: {"Content-Type": "application/json"},
      body: jsonEncode({"id_token": idToken}),
    );
  }
}

需求2:Django接口校验Firebase认证状态

  • 第一步:Django项目初始化Firebase Admin SDK,先从Firebase控制台下载服务账号JSON文件放到项目根目录,然后在项目根目录的__init__.py中添加初始化代码:
# 项目根目录/__init__.py
import firebase_admin
from firebase_admin import credentials
import os

if not firebase_admin._apps:
    cred = credentials.Certificate(os.path.join(os.path.dirname(__file__), "你的服务账号文件名.json"))
    firebase_admin.initialize_app(cred)
  • 第二步:编写DRF自定义认证类,自动校验请求携带的Firebase凭证:
# 你的应用/authentication.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from firebase_admin import auth
from .models import CustomUser

class FirebaseAuthentication(BaseAuthentication):
    def authenticate(self, request):
        auth_header = request.META.get("HTTP_AUTHORIZATION")
        # 没有携带认证头的请求直接跳过
        if not auth_header or not auth_header.startswith("Bearer "):
            return None
        
        id_token = auth_header.split(" ")[1]
        try:
            decoded_token = auth.verify_id_token(id_token)
            firebase_uid = decoded_token["uid"]
        except Exception as e:
            raise AuthenticationFailed("认证凭证无效或已过期")
        
        try:
            user = CustomUser.objects.get(firebase_uid=firebase_uid)
        except CustomUser.DoesNotExist:
            raise AuthenticationFailed("用户未同步到系统")
        
        return (user, None)
  • 第三步:配置DRF默认使用该认证类,也可以给需要的接口单独指定:
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        '你的应用名.authentication.FirebaseAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated', # 全局接口默认需要认证,不需要认证的接口单独设置permission_classes = [AllowAny]
    ]
}
  • 第四步:Flutter端所有请求Django接口时,在请求头携带Firebase id token即可:
// Flutter 请求示例
Future<void> fetchUserInfo() async {
  User? currentUser = FirebaseAuth.instance.currentUser;
  if (currentUser != null) {
    String? idToken = await currentUser.getIdToken();
    var response = await http.get(
      Uri.parse("你的Django服务地址/api/user/info/"),
      headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer $idToken"
      },
    );
    // 处理返回结果
  }
}

注意事项

  • Firebase的id token默认有效期1小时,Flutter的getIdToken()方法会自动刷新过期的token,不需要手动处理刷新逻辑
  • 如果用户在Firebase端被禁用、注销,Django侧校验token时会直接返回认证失败,符合安全要求
  • 同步用户接口支持重复调用,不会出现重复创建用户的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 04:54:04