概括
如何在 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(请求))