概括
如何在 Django + MongoEngine 中使用自定义用户模型和自定义身份验证后端(以允许电子邮件/密码身份验证)? (是否需要自定义后端?......即,在使用 MongoEngine 进行身份验证时使用电子邮件作为用户名。)
在 Django 中进行身份验证时,在使用Mongo作为主数据存储的同时使用自定义用户对象的直接(且完整!)示例是否有任何文档?(Postgres 有更清晰、更全面的文档……)
细节
MongoEngine 似乎只给你两种身份验证方式——“经典”(又名“ mongoengine.django.auth.MongoEngineBackend ”)方式......或者......“自定义用户模型”(又名“ django.contrib.auth ”) .backends.ModelBackend ') 方式——在 Nicolas Cortot 对这里另一个问题的回答中或多或少地简洁地概述了这两种方式:
Python-Social-Auth failed with mongoEngine (Django)
这两种身份验证技术都使您可以访问类似于 Django 的 AbstractBaseUser 类的authenticate()方法——该方法依赖于check_password函数。但是,在您使用所谓的“自定义用户模型”身份验证风格(如上面的链接中所述)的那一刻......然后将其与自定义后端配对(以便使用电子邮件作为用户名)......你由于无法访问典型的 authenticate() 函数而遇到麻烦。
比如像这样...
account.models.py
# ...使用 postgres,我将继承 AbstractBaseUser...但使用 Mongo...(?) 从 django.conf 导入设置 从 mongoengine.fields 导入 EmailField, BooleanField
从 mongoengine.django.auth 导入用户 类我的用户(用户): email = EmailField(max_length=254, unique=True) is_active = BooleanField(默认=真) is_admin = BooleanField(默认=假) USERNAME_FIELD = '电子邮件' REQUIRED_FIELDS = '' ...
my_custom_backend.py
# ...是否需要自定义后端才能使用电子邮件而不是用户名进行身份验证?
从 django.conf 导入设置
从 django.contrib.auth.models 导入 check_password
#from mongoengine.django.auth 导入 check_password
#from django.contrib.auth.hashers 导入 check_password
从模型导入 MyUser
类 EmailAuthBackend(对象):
def 身份验证(自我,电子邮件=无,密码=无):
# ...呃哦,因为我没有使用带有预先存在的 authenticate() 的常用后端之一
# 方法,没有可用的本机 check_password() 函数。意味着我必须散列
#密码等
所以,看起来,我有义务编写自己的 check_password 函数。为了获得通常在 PostgreSQL 身份验证中发现的AbstractBaseUser类固有的所有优点,我必须完全扩展我的自定义用户模型,这看起来很老套,而且不能很干。
我在这里完全糊涂了吗?...即,如果我想在使用 MongoEngine 时使用电子邮件而不是用户名进行身份验证,是否真的完全没有必要使用自定义后端?
我觉得我可能对 Django 在身份验证方面如何与 MongoEngine 一起工作,以及我在该过程中如何建模和调用自定义用户对象/我的 MongoEngine 用户对象的特定子类有一个基本的误解......
因为——就像现在一样——我在浏览器中收到“ 'AnonymousUser' 对象没有属性'backend' ”错误消息。我还注意到这个问题有时会因为意想不到的原因而存在——即:可能,authenticate() 方法需要一个散列密码,或者因为登录名(电子邮件)太长......?有关可能属于后一种情况的更多情况,请参阅:
Django 注册表单“AnonymousUser”对象没有属性“后端”
设置.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'mongoengine.django.mongo_auth',
'帐户',
)
AUTHENTICATION_BACKENDS = (
'mongoengine.django.auth.MongoEngineBackend',
#'accounts.my_custom_backend.EmailAuthBackend',
#'django.contrib.auth.backends.ModelBackend',
)
AUTH_USER_MODEL = 'mongo_auth.MongoUser'
MONGOENGINE_USER_DOCUMENT = 'accounts.models.User'
帐户.views.py
从 django.contrib.auth 导入登录为 django_login
从 my_custom_backend 导入 EmailAuthBackend
从表单导入 AuthenticationForm
def 登录(请求):
表单 = AuthenticationForm(data=request.POST)
如果 form.is_valid():
尝试:
后端 = EmailAuthBackend()
用户 = backend.authenticate(email=request.POST['email'], password=request.POST['password'])
django_login(请求,用户)
返回重定向('/')
除了不存在:
return HttpResponse('用户不存在')
别的:
表单 = AuthenticationForm()
return render_to_response('accounts/login.html',
{“形式”:形式},
context_instance=RequestContext(请求))