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

Django多租户社交登录:如何注入租户自有Google OAuth2凭证?

多租户Django应用动态注入Google OAuth2凭证方案

完全可以实现,核心是针对单个请求动态配置社交认证后端的凭证,而非修改全局Settings(毕竟全局配置仅在启动时加载,无法支持多租户隔离)。以下是具体实现步骤:

1. 自定义ConvertTokenView

继承drf_social_oauth2的ConvertTokenView,在处理请求时根据当前租户的schema获取专属Google凭证,再给后端实例动态赋值:

from drf_social_oauth2.views import ConvertTokenView, get_access_token
from django_tenants.utils import get_tenant_model
from social_core.backends.google import GoogleOAuth2
from rest_framework.response import Response
from rest_framework import status
from oauth2_provider.models import Application

class TenantConvertTokenView(ConvertTokenView):
    def post(self, request, *args, **kwargs):
        # 从请求中识别当前租户(依赖django-tenants的租户上下文)
        tenant = get_tenant_model().objects.get(schema_name=request.tenant.schema_name)
        
        # 校验租户是否配置了有效Google凭证
        if not all([tenant.google_client_id, tenant.google_client_secret]):
            return Response(
                {"error": "当前租户未配置Google OAuth2认证凭证"},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 只处理Google OAuth2的转换请求,其他走原有逻辑
        backend_name = request.data.get("backend")
        if backend_name != "google-oauth2":
            return super().post(request, *args, **kwargs)
        
        # 实例化Google后端并动态设置租户专属凭证
        google_backend = GoogleOAuth2()
        google_backend.setting("KEY", tenant.google_client_id)
        google_backend.setting("SECRET", tenant.google_client_secret)
        
        # 用租户凭证完成Google认证
        try:
            user = google_backend.do_auth(request.data.get("token"))
            if not user:
                return Response(
                    {"error": "Google账号认证失败"},
                    status=status.HTTP_401_UNAUTHORIZED
                )
            
            # 复用drf_social_oauth2的逻辑生成OAuth2令牌
            app = Application.objects.get(name="your-oauth-app-name")  # 替换为你的OAuth应用名称
            access_token, _ = get_access_token(user, app)
            
            return Response({
                "access_token": access_token.token,
                "token_type": "Bearer",
                "expires_in": access_token.expires_in,
                "refresh_token": access_token.refresh_token.token,
                "scope": access_token.scope
            })
        except Exception as e:
            return Response(
                {"error": str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )

2. 更新URL路由

把原有的ConvertTokenView替换为自定义视图:

from django.urls import path
from .views import TenantConvertTokenView

urlpatterns = [
    # 替换默认的convert-token接口
    path("auth/convert-token/", TenantConvertTokenView.as_view(), name="convert-token"),
    # 其他路由...
]

3. 扩展租户模型存储凭证

在你的租户模型中添加字段,用于存储每个租户的Google OAuth2凭证:

from django_tenants.models import TenantMixin, DomainMixin
from django.db import models

class Tenant(TenantMixin):
    name = models.CharField(max_length=100)
    paid_until = models.DateField(null=True, blank=True)
    on_trial = models.BooleanField(default=True)
    created_on = models.DateField(auto_now_add=True)
    # 新增Google凭证字段
    google_client_id = models.CharField(max_length=255, null=True, blank=True)
    google_client_secret = models.CharField(max_length=255, null=True, blank=True)
    
    auto_create_schema = True  # 自动创建schema

class Domain(DomainMixin):
    pass

关键注意点

  • 并发安全:每个请求单独实例化GoogleOAuth2后端,避免多租户请求之间的凭证冲突,绝对不要修改全局后端配置。
  • 逻辑复用:尽量复用drf_social_oauth2和python-social-auth的内置方法(如do_auth、get_access_token),减少自定义逻辑的维护成本。
  • 扩展性:如果后续要支持其他社交平台(如Facebook),只需针对对应后端类(如FacebookOAuth2)做同样的动态凭证配置即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:17:06