Django 管理员不使用自定义身份验证后端

Sol*_*ong 2 python authentication django

我有一个自定义用户模型和一个身份验证后端。当我使用 shell 时,身份验证功能工作正常,但是当涉及到管理站点登录时,它就不起作用了。

代码来自官方 Django 文档

设置.py

# Authentication
AUTH_USER_MODEL = 'BBUser.UserInfo'
AUTHENTICATION_BACKENDS = [
    'BBUser.models.AuthBackend',
    'BBUser.models.AdminAuthBackend',
]
Run Code Online (Sandbox Code Playgroud)

模型.py

class UserInfo(AbstractBaseUser, PermissionsMixin):
    openid = models.CharField(max_length=50, null=False, unique=True)
    nickname = models.CharField(max_length=30, null=True)
    ...

    USERNAME_FIELD = 'openid'
    REQUIRED_FIELDS = []
    ...

    objects = UserManager()


class AdminAuthBackend(object):
    def authenticate(self, openid=None, password=None):
        print "custom auth"
        login_valid = ('100' == openid)
        pwd_valid = ('tobeno.2' == password)
        if login_valid and pwd_valid:
            try:
                user = UserInfo.objects.get(openid=openid)
            except UserInfo.DoesNotExist:
                user = UserInfo(openid=openid, password='get from .py')
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        try:
            return UserInfo.objects.get(pk=user_id)
        except UserInfo.DoesNotExist:
            return None
Run Code Online (Sandbox Code Playgroud)

由于我print在 AdminAuthBackend.authenticate() 中放置了一个,所以我知道它何时执行。

当我authenticate()从 shell调用时,自定义 auth 方法在管理页面中被调用,它不是。

任何帮助表示赞赏。

Sol*_*ong 5

我自己找到了答案。

在深入研究 Django 的源代码后,我发现这个片段django.contrib.auth.forms处理来自管理站点登录表单的 post 请求:

def clean(self):
    username = self.cleaned_data.get('username')
    password = self.cleaned_data.get('password')

    if username and password:
        self.user_cache = authenticate(username=username,
                                       password=password)
        if self.user_cache is None:
            raise forms.ValidationError(
                self.error_messages['invalid_login'],
                code='invalid_login',
                params={'username': self.username_field.verbose_name},
            )
        else:
            self.confirm_login_allowed(self.user_cache)

    return self.cleaned_data
Run Code Online (Sandbox Code Playgroud)

请注意,虽然它用于auth.authentication处理登录操作,但它实际上解析了固定字段usernamepassword,这意味着默认的管理站点登录表单会忽略您自己的 AuthenticationBackends。

为了解决这个问题,我需要为管理站点实现我自己的登录表单。


cha*_*ADE 5

这是我的解决方案..希望它能帮助某人:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend' #add this line
    'your auth backend'
]
Run Code Online (Sandbox Code Playgroud)

保留默认的django.contrib.auth.backends.ModelBackend类,以确保 django 管理使用默认的用户名/密码身份验证工作流程。然后添加您的自定义身份验证后端类,以便您可以进行更改。