3

我正在尝试设置一个自定义后端来查询另一个数据库,为此我在系统中创建了一个模型。它使用自己的规则(电子邮件而不是用户名,以及不同的加盐/哈希密码),所以我不能使用内置身份验证。我已经设置了一个自定义身份验证后端,如下所示:

class BlahBlahBackend:

    def check_password():
        # check password code here
        return true

    def authenticate(self, email=None, password=None):
        import myapp.models.loginmodel
        try:
            person =  myapp.models.loginmodel.People.objects.get(email=email)
            if check_password(password, person.password):
                try:
                    user = User.objects.get(email=email)
                except User.DoesNotExist:
                    username=person.first_name + person.last_name
                    name_count = User.objects.filter(username__startswith = username).count()
                    if name_count:
                        username = '%s%s'%(username, name_count + 1)
                        user = User.objects.create_user(username,email)
                    else:
                        user = User.objects.create_user(username,email)
        except People.DoesNotExist:
            return None

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

我添加了 BlahBlahBackend 作为身份验证后端:

AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'socialauth.auth_backends.OpenIdBackend', 'socialauth.auth_backends.TwitterBackend', 'socialauth.auth_backends.FacebookBackend', 'socialauth.auth_backends.BlahBlahBackend', )

如您所见,我还使用了一些预先存在的身份验证后端,这些后端也在 socialauth 中。

我有一个指向以下观点的提交表单:

def blahblah_login_complete(request):
    email = request.POST.get('email')
    password = request.POST.get('password')
    user = authenticate(email,password)
    # if user is authenticated then login user
    if user:
        login(request, user)
    else:
        return HttpResponseRedirect(reverse('socialauth_login_page'))

但是,当我尝试以这种方式登录时,似乎一个或多个其他后端的行为就好像我正在尝试使用他们的方法登录一样。

我读到后端已缓存,因此运行

Session.objects.all().delete()

清除后端缓存。

我的主要问题是:

  1. AUTHENTICATION_BACKENDS 中列出项目的顺序
  2. 系统如何决定/知道使用哪个后端?任何文档都没有明确说明这一点,我觉得这有点令人困惑。
  3. 有没有办法根据请求强制使用特定的授权。换句话说,如果有人提交表单,有没有办法强制他们使用基于表单登录的身份验证,而不是通过 openid 或 Twitter 登录?

更新:

有用!这很酷,谢谢。我想 django 文档似乎在说“你不必做任何其他事情,它就像魔术一样工作”,事实证明确实如此。只要后端在那里并且凭据设置正确,身份验证就会起作用。事实证明,真正的问题是 urls.py 文件中的错误配置,没有将登录表单中的帖子发送到正确的处理程序,这就是它一直尝试使用另一种身份验证方法的原因。

4

3 回答 3

1
  1. 这里有清楚的描述 - django 按定义的顺序尝试每个后端,如果第一次验证失败,它会转到第二个等。

  2. 我相信您可以动态加载后端类并直接通过它进行身份验证。查看 django authenticate() 函数源以了解如何执行此操作。

于 2010-01-28T09:11:50.520 回答
1

您应该对 django.contrib.auth.authenticate() 使用关键字参数。名称应该与后端验证方法中的参数名称匹配。默认后端处理名称“用户名”和“密码”。

您的后端可以为关键字参数使用不同的名称,例如:blahblah_email 和 blahblah_password,然后调用 authenticate(blahblah_email=..., blahblah_password=...)。

于 2010-01-28T09:24:53.797 回答
1

我想django-cas对你来说是一个很好的参考:)

是的,AUTHENTICATION_BACKENDS 的顺序很重要。

Django 遍历 backends 列表并在第一个后端停止,该后端具有authenticate接受您传递给它的凭证参数的方法。

于 2010-01-28T15:32:16.467 回答