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有效性,确认用户为管理员:
- 安装依赖库:
pip install pyjwt requests
- 编写验证逻辑(可封装为中间件或装饰器):
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('无效的身份凭证')
- 将此逻辑添加到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
相关产品推荐
相关产品推荐

