我正在尝试设置一个查询另一个数据库的自定义后端,我已经在系统中创建了一个模型。它使用自己的规则(电子邮件而不是用户名,以及不同的盐渍/哈希密码),因此我无法使用内置身份验证。我已经设置了一个自定义身份验证后端,如下所示:
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', )
正如您所看到的,我还使用了一些预先存在的auth后端,这些后端也属于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()
清除后端缓存。
我的主要问题是:
更新
有效!这非常酷,谢谢。我想这似乎是django doc说“你不需要做任何其他事情,它只是像魔术一样工作”,事实证明这是绝对的情况。只要后端存在并且凭据设置正确,身份验证就可以运行。事实证明,真正的问题是urls.py文件中的配置错误,该文件没有将帖子从登录表单发送到正确的处理程序,这就是它继续尝试使用其他身份验证方法的原因。
答案 0 :(得分:1)
这里有清楚的描述 - django按顺序尝试每个后端 定义,如果第一次失败 认证它进入第二等。
我相信您可以动态加载后端类并进行身份验证 直接通过它。看看django authenticate()函数来源如何做到这一点。
答案 1 :(得分:1)
你应该使用django.contrib.auth.authenticate()的关键字参数名称应该与后端的authenticate方法中的参数名称相匹配。默认后端处理名称'username'& '密码'。
您的后端可以为关键字参数使用不同的名称,例如:blahblah_email和blahblah_password,然后调用authenticate(blahblah_email = ...,blahblah_password = ...)。
答案 2 :(得分:1)
我想django-cas对你来说是一个很好的参考:)
是的,AUTHENTICATION_BACKENDS的顺序很重要。
Django循环遍历后端列表,并在第一个后端停止,该后端具有authenticate
方法,接受您传递给它的凭据参数。