具有多个数据库的 Django 身份验证

Django authentication with multiple databases

我想为客户创建一个应用程序,其中每个客户都有自己的数据库。因此,作为登录信息,他们需要输入三个不同的字段:客户编号、用户名、密码。

用户名和密码应该做正常的身份验证工作,客户编号在那里转到正确的数据库用户 table 进行身份验证我可以通过 using() 函数转到其他数据库。

class CustomAuthBackend(ModelBackend):

def authenticate(self, request, username=None, password=None, **kwargs):
    user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
    if user.check_password(password) and self.user_can_authenticate(user) :
         try:
            user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
            return user
         except User.DoesNotExist:
            return None

def get_user(self, user_id):
    try:
        return CustomUser.objects.get(pk=user_id)
    except User.DoesNotExist:
        return None

身份验证功能工作正常,我猜我遇到的问题是 get_user 功能,因为 get_user 功能没有请求,我可以在哪里定义它应该调用哪个数据库。因为每次我调用 {% if user.is_authenticated %} 它都会转到默认数据库并说用户是匿名的。 我不知道解决这个问题的正确方法是我的解决方案错了吗?

好的,在尝试了一些东西之后我得到了一个解决方案,我认为它对第一步有效,但我不知道如果我这样使用它是否存在安全问题或任何其他错误

from app.models import CustomUser
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import login as auth_login
from app.middleware import ThreadLocal

class CustomAuthBackend(ModelBackend):

def authenticate(self, request, username=None, password=None, **kwargs):
    user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
    if user.check_password(password) and self.user_can_authenticate(user) :
         try:
            user = CustomUser.objects.using(request.POST['kundennr']).get(username=username)
            request.session['kundennr']=request.POST['kundennr']
            return user
         except User.DoesNotExist:
            return None

def get_user(self, user_id):
    try:
        request = ThreadLocal.get_current_request()
        return CustomUser.objects.using(request.session['kundennr']).get(pk=user_id)
    except User.DoesNotExist:
        return None

我将 ThreadLocal.py 导入到中间件中,这样我就可以在 get_user 中获取请求对象,当我登录时,我将客户保存到我在 get_user 中调用的会话变量中,然后这个解决方案是否可以接受或者是否存在一些风险?