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

React SPA的Firebase Auth与GCP Cloud Run Django管理面板认证联动问题

解决方案:打通Firebase Auth与Django管理面板的跨子域认证

一、直接传递Firebase JWT到子域名的可行性及实现步骤

可以通过跨子域Cookie实现Firebase Auth生成的JWT在主域与子域间自动传递,具体操作如下:

1. 在React主应用中设置跨子域Cookie

用户登录后,从Firebase获取ID Token并设置为跨子域Cookie:

// React中获取Firebase ID Token并设置Cookie
firebase.auth().currentUser.getIdToken(true)
  .then(idToken => {
    // 设置Cookie,domain为主域(如.example.com),确保子域名可读取
    document.cookie = `firebase_id_token=${idToken}; path=/; domain=.your-main-domain.com; secure; samesite=lax`;
  })
  .catch(error => {
    console.error('获取ID Token失败:', error);
  });
  • 注意:domain需设置为主域名(前缀加.),比如主域是example.com,子域是admin.example.com,则domain=.example.com
  • secure确保Cookie仅在HTTPS下传输,samesite=lax降低CSRF风险
  • 此方式设置的Cookie无法标记为HttpOnly(JS限制),需注意XSS防护(比如主应用严格的内容安全策略)

2. 在Django中验证Firebase JWT

Django端需要验证Cookie中的ID Token有效性,确认用户为管理员:

  1. 安装依赖库:
pip install pyjwt requests
  1. 编写验证逻辑(可封装为中间件或装饰器):
import jwt
import requests
from django.http import HttpResponseForbidden

# 从Firebase获取公钥(缓存公钥避免重复请求)
FIREBASE_PUBLIC_KEYS = requests.get('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com').json()

def verify_firebase_token(request):
    token = request.COOKIES.get('firebase_id_token')
    if not token:
        return HttpResponseForbidden('未提供身份凭证')
    
    try:
        # 解析JWT头获取对应的公钥ID
        header = jwt.get_unverified_header(token)
        public_key = FIREBASE_PUBLIC_KEYS[header['kid']]
        # 验证Token,替换为你的Firebase项目ID
        decoded_token = jwt.decode(
            token,
            public_key,
            algorithms=['RS256'],
            audience='your-firebase-project-id',
            issuer='https://securetoken.google.com/your-firebase-project-id'
        )
        
        # 检查用户邮箱是否为管理员(可结合数据库或配置)
        admin_emails = {'admin@example.com', 'manager@example.com'}
        if decoded_token['email'] not in admin_emails:
            return HttpResponseForbidden('无管理员权限')
        
        # 将用户信息存入request,供后续视图使用
        request.user = decoded_token
        return None
    except jwt.InvalidTokenError:
        return HttpResponseForbidden('无效的身份凭证')
  1. 将此逻辑添加到Django的中间件中,对所有管理面板路由生效。

二、替代方案(若跨子域Cookie方案不符合需求)

方案1:Firebase OAuth2集成Django

让Django作为Firebase OAuth2的客户端,共享身份源:

  • 在Firebase控制台添加Django子域名的OAuth回调URL(如https://admin.example.com/auth/firebase/callback)
  • 使用social-auth-app-django库配置Firebase作为认证提供商,实现Django的登录流程
  • 主应用中添加“进入管理面板”按钮,直接跳转至Django的Firebase登录入口,登录成功后Django验证用户邮箱是否为管理员,创建本地会话

方案2:GCP Identity-Aware Proxy(IAP)强化认证

利用GCP IAP接管Cloud Run的访问控制,结合Firebase Auth实现统一认证:

  • 为Cloud Run服务启用IAP,配置Firebase Auth作为自定义身份提供商
  • 在IAP中设置访问权限,仅允许指定管理员邮箱访问
  • 主应用中已登录的用户访问子域名时,IAP会自动验证Firebase身份,无需手动传递JWT

方案3:共享会话存储

通过第三方存储(如Redis、Firestore)共享主应用与Django的会话:

  • 主应用登录后,将Firebase用户信息存入共享存储,并生成会话ID
  • 将会话ID设置为跨子域Cookie
  • Django读取Cookie中的会话ID,从共享存储中获取用户信息并验证权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:27:13