本文介绍了MongoEngine - 如何将自定义的用户模式/用于身份验证的自定义后端()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘要

如何使用自定义的用户模型的的自定义认证后端(允许电子邮件/密码认证)和Django + MongoEngine?(是一个自定义的后端连必要的是什么?......即与MongoEngine身份验证时使用电子邮件用户名)。

是否与使用的自定义用户对象的直进(完整!)例如任何文件,而使用蒙戈的作为主要的数据存储时验证的吗(Postgres有这样更清晰,更融为一体prehensive文档...)

结果

详细信息

MongoEngine似乎只给你两种身份验证的口味 - 经典(又名的 mongoengine.django.auth.MongoEngineBackend 的')的方式......或者......自定义用户模型(又名的 django.contrib.auth.backends.ModelBackend 的')的方式 - 这两者或多或少简洁的尼古拉斯·科尔托的回答概括这里一个不同的问题:搜索结果
Python-Social-Auth失败mongoEngine(Django的)

这两种认证技术使您可以访问到的认证()的方法类似Django的AbstractBaseUser类 - 这依赖于* check_password *功能的方法。但是,你分钟使用的身份验证的所谓的自定义用户模型的味道(如上面的链接概述)... 的配对,然后与定制的后端(为了使用电子邮件对于用户名)...你遇到麻烦,由于没有进入典型的身份验证()函数。

例如,像这样......

accounts.models.py

结果


#...在Postgres,我会继承AbstractBaseUser ...但是...蒙戈(?)从django.conf导入设置
从mongoengine.fields导入EmailField,BooleanField结果
从mongoengine.django.auth导入用户类MYUSER(用户):    电子邮件= EmailField(MAX_LENGTH = 254,独特= TRUE)
    IS_ACTIVE = BooleanField(默认为真)
    is_admin = BooleanField(默认值= FALSE)    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认证(个体经营,电子邮件=无,密码=无):#...嗯哦,因为我没有使用了pre-现有的认证通常后端之一()
#方法,没有可用的天然check_password()函数。意味着我必须散列
#密码等。

因此​​,看似的,我有义务写我自己的check_password功能。为了让所有的善良与内在的 AbstractBaseUser 的通常发现PostgreSQL的认证类,我不得不完全夸大我的自定义用户模型,这似乎哈克并不能很干。

我是否得到完全糊涂了吗? ......即,它实际上是完全没有必要使用自定义的后端,如果我想用MongoEngine时使用电子邮件,而不是用户名进行身份验证?

我觉得我可能有Django中如何与MongoEngine关于验证的根本性的误解,并就我建模方式,并呼吁自定义用户对象,在这个过程MongoEngine的用户对象的/我的具体子类。 ..

由于 - 因为它是现在 - 我得到一个AnonymousUser对象有没有属性'后台'的错误在浏览器中的消息。我也注意到这个问题有时会存在意想不到的原因 - 即:也许,authenticate()方法需要一个哈希密码,或者是因为登录(电子邮件)太长...?欲了解更多情况,其中后一种情况可能是这样,请参见:

Django登记表AnonymousUser对象有没有属性'后台'

结果

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高清登录(要求):    形式= AuthenticationForm(数据= request.POST)
    如果form.is_valid():
        尝试:
            后端= EmailAuthBackend()
            用户= backend.authenticate(电子邮件= request.POST ['邮件'],密码= request.POST ['密码'])
            django_login(请求,用户)
            返回重定向('/')
        除了DoesNotExist:
            返回的Htt presponse(用户不存在)
    其他:
        形式= AuthenticationForm()    返回render_to_response(账户/ login.html的,
       {形式:形式},
       context_instance = RequestContext的(要求))


解决方案

好吧,貌似行动最好的办法是不要Django的用户移交给蒙戈认证开始与...得到通过Twitter这个黄金金块

我的答案很简单:尽量避免与更换的MongoDB Django的用户模型。你失去所有的Django的权力,失去MongoDB的速度。
严重的是,用户涉及到的一切,MongoDB是没有关系的。

&MDASH。丹尼尔·罗伊·格林菲尔德(@pydanny)



所以:我就利用PostgreSQL的认证,并蒙戈其他对象。这意味着命名/连接到Django的设置两个数据库。现在回想起来,我猜的寓意是:从来没有使用蒙戈仅仅因为它很酷。蒙戈仍然在Django的世界二等公民。

SUMMARY

How do I use a custom User model and a custom authentication backend (to allow for email / password authentication) with Django + MongoEngine? (Is a custom backend even necessary for that? ...i.e., to use an email for username when authenticating with MongoEngine.)

Is there any documentation with a straight-forward (and complete!) example of using a custom user object while using Mongo as the primary datastore when authenticating in Django? (Postgres has such clearer and more comprehensive docs...)


DETAIL

MongoEngine seems to give you just two flavors of authentication--the "Classic" (aka 'mongoengine.django.auth.MongoEngineBackend') way...OR...the "Custom User Model" (aka 'django.contrib.auth.backends.ModelBackend') way--both of which more or less succinctly outlined in Nicolas Cortot's answer to a different question here:

Python-Social-Auth fails with mongoEngine (Django)

Both of these authentication techniques give you access to an authenticate() method similar to Django's AbstractBaseUser class--a method which relies on a *check_password* function. However, the minute you use the so-called "Custom User Model" flavor of authentication (as outlined in the above link)...and then pair that with a custom backend (in order to use emails for usernames)...you run into trouble due to the absence of access to the typical authenticate() function.

For example, like so...

accounts.models.py


# ...with postgres, I'd subclass AbstractBaseUser...but with Mongo...(?)

from django.conf import settings
from mongoengine.fields import EmailField, BooleanField 
from mongoengine.django.auth import User class MyUser(User): email = EmailField(max_length=254, unique=True) is_active = BooleanField(default=True) is_admin = BooleanField(default=False) USERNAME_FIELD = 'email' REQUIRED_FIELDS = '' ...


my_custom_backend.py

# ...is a custom backend even necessary to use email for authentication instead of username?

from django.conf import settings
from django.contrib.auth.models import check_password
#from mongoengine.django.auth import check_password
#from django.contrib.auth.hashers import check_password
from models import MyUser

    class EmailAuthBackend(object):

        def authenticate(self, email=None, password=None):

# ...uh oh, since I'm NOT using one of the usual backends with a pre-existing authenticate()
# method, there ain't a native check_password() function available. Means I have to hash the
# password, etc.

So, seemingly, I'm obliged to write my own check_password function. To get all of the goodness inherent with the AbstractBaseUser class typically found with a PostgreSQL authentication, I'd have to totally inflate my custom User model, which seems hacky and can't be very DRY.

Am I getting totally confused here? ...i.e., is it actually totally unnecessary to use a custom backend if I want to use emails instead of usernames for authentication when using MongoEngine?

I feel like I may have a fundamental misunderstanding of how Django works with MongoEngine in regard to authentication, and with regard to how I've modeled and called upon custom user object / my particular subclassing of MongoEngine's user object during that process...

Because--as it is right now--I'm getting an "'AnonymousUser' object has no attribute 'backend'" error message in the browser. I also noted that this problem sometimes exists for unexpected reasons--namely: perhaps, the authenticate() method expects a hashed password, or because the login (email) is too long...? For more instances where this latter circumstance might be the case, see:

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',
    'accounts',
)

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

from django.contrib.auth import login as django_login
from my_custom_backend import EmailAuthBackend
from forms import AuthenticationForm

def login(request):

    form = AuthenticationForm(data=request.POST)
    if form.is_valid():
        try:
            backend = EmailAuthBackend()
            user = backend.authenticate(email=request.POST['email'], password=request.POST['password'])
            django_login(request, user)
            return redirect('/')
        except DoesNotExist:
            return HttpResponse('user does not exist')
    else:
        form = AuthenticationForm()

    return render_to_response('accounts/login.html',
       { 'form': form },
       context_instance=RequestContext(request))
解决方案

Well, looks like the best course of action isn't to hand over Django's User to Mongo for authentication to begin with... Got this golden nugget via Twitter:

@blogblimp my short answer: try to avoid replacing Django user models with MongoDB. You lose all the Django power and lose MongoDB's speed.Seriously, user relates to everything and MongoDB isn't relational.

— Daniel Roy Greenfeld (@pydanny) January 20, 2014


So: I'll just leverage PostgreSQL for authentication, and Mongo for other objects. That means naming / connecting to two databases in the Django settings. In retrospect, I guess the moral is: never use Mongo just because it's cool. Mongo is still a second-class citizen in the Django world.

这篇关于MongoEngine - 如何将自定义的用户模式/用于身份验证的自定义后端()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 06:39