【发布时间】:2014-01-31 02:17:22
【问题描述】:
摘要
如何在 Django + MongoEngine 中使用自定义用户模型和自定义身份验证后端(以允许电子邮件/密码身份验证)?(甚至是自定义后端有必要吗?...即,在使用 MongoEngine 进行身份验证时使用电子邮件作为用户名。)
是否有任何文档包含使用 自定义用户对象同时使用 Mongo 作为主数据存储的直接(且完整!)示例authenticating 在 Django 中?(Postgres 有这样更清晰、更全面的文档...)
详情
MongoEngine 似乎只为您提供两种身份验证方式——“经典”(又名 'mongoengine.django.auth.MongoEngineBackend')方式......或者......“自定义用户”模型”(又名 'django.contrib.auth.backends.ModelBackend')方式——在 Nicolas Cortot 对不同问题的回答中或多或少地简洁地概述了这两种方式:
Python-Social-Auth fails with mongoEngine (Django)
这两种身份验证技术都可以让您访问类似于 Django 的 AbstractBaseUser 类的 authenticate() 方法——该方法依赖于 check_password 函数。但是,在您使用所谓的“自定义用户模型”身份验证风格(如上面的链接中所述)的那一刻......并且然后将其与自定义后端配对(以便使用电子邮件对于用户名)...由于无法访问典型的 authenticate() 函数,您会遇到麻烦。
例如,像这样……
accounts.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 类固有的所有优点,我必须完全扩展我的自定义用户模型,这看起来很老套,而且不太干。 p>
我在这里完全糊涂了吗? ...即,如果我想在使用 MongoEngine 时使用电子邮件而不是用户名进行身份验证,是否真的完全不需要使用自定义后端?
我觉得我可能对 Django 在身份验证方面如何与 MongoEngine 一起工作,以及我在该过程中如何建模和调用自定义用户对象/我的 MongoEngine 用户对象的特定子类存在根本性的误解。 ..
因为 - 就像现在一样 - 我在浏览器中收到“'AnonymousUser' 对象没有属性 'backend'”错误消息。我还注意到这个问题有时会因为意想不到的原因而存在——即:也许,authenticate() 方法需要一个散列密码,或者因为登录名(电子邮件)太长......?有关可能属于后一种情况的更多情况,请参阅:
Django Register Form 'AnonymousUser' object has no attribute 'backend'
settings.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'accounts.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(请求))【问题讨论】:
标签: django authentication mongoengine custom-backend