Django - 读取当前用户认证后端类

4 投票
3 回答
4247 浏览
提问于 2025-04-16 11:58

我在用Django做一个自定义的认证系统,目的是从一个旧系统里自动创建用户并让他们登录。我的Backend类是这样的:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from sfi.models import Employee
import base64, hashlib

class SFIUserBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        if not username or not password:
            return

        digest = base64.standard_b64encode(hashlib.md5(password).digest())
        user = None
        try:
            employee = Employee.objects.get(login=username, passwd=digest)
            user, created = User.objects.get_or_create(username=username)
            if created:
                # setting attributes
                user.first_name = employee.names[:30]
                user.last_name = employee.surnames[:30]
                user.is_staff = True
                user.save()
        except Employee.DoesNotExist:
            pass

        return user

到目前为止,这个功能运行得很好。不过,我需要在模板里读取当前登录用户的后端类。

当我用request.user.backend时,它显示user没有这个属性... 而我也不能从会话中读取这个信息(用request.session._auth_user_backend),因为Django的模板系统会抱怨说“变量和属性不能以下划线开头”。

我正在使用django.contrib.auth.views.login来让用户登录。我缺少了什么呢?

3 个回答

0

在使用 authenticate() 函数时,它会给用户添加一个叫 user.backend 的属性,而 login() 函数则会把这个属性保存到会话中。不过,奇怪的是,get_user() 函数并没有把这个属性再加回到用户身上。我已经提交了一个修复方案。

所以,如果你想在另一个请求中访问这个属性,你需要用 request.session[django.contrib.auth.BACKEND_SESSION_KEY] 来获取它。

你也可以写一个自定义标签,或者把它添加到你的上下文中(可以用你想要的任何名字),这样使用起来会更方便。

0

你应该在视图中读取它,然后以一种适合人类理解的方式发送这个类名作为消息。

2

当用户通过 django.contrib.auth.authenticate(username='foo',password='bar') 这个函数进行身份验证时,backend 属性会被添加到 user 对象上。

这个函数会依次调用你在 settings.py 文件中指定的所有 AUTHENTICATION_BACKENDS,直到成功通过其中一个进行身份验证。

如果你的用户已经“登录”了,但没有 backend 属性,这可能意味着你没有正确地进行身份验证。也许你直接调用了 SFIUserBackend.authenticate 函数,而应该调用 django.contrib.auth.authenticate 函数?

可以查看这些 自定义身份验证文档

撰写回答