MongoEngine - 如何自定义用户模型/自定义后端的authenticate() [英] MongoEngine -- how to custom User model / custom backend for authenticate()

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

问题描述

摘要



如何使用自定义用户模型自定义身份验证后端允许使用Django + MongoEngine进行电子邮件/密码验证?(是否需要自定义后端?即使在使用MongoEngine进行身份验证时使用电子邮件用户名。)



在使用 Mongo 时,是否有任何使用自定义用户对象的直接(和完整!)示例的文档作为Django中认证的主数据存储区?(Postgres有更清晰,更全面的文档...)






细节



MongoEngine似乎给你只有两种认证 - - 经典(又名'mongoengine.django.auth.MongoEngineBackend ')方式...或...自定义用户模型(又名为django.contrib.auth)。 backend.ModelBackend ')方式 - 这两种或多或少的succ在Nicolas Cortot对这个不同的问题的答案中概述:


Python-Social-Auth失败与mongoEngine(Django)



这两种身份验证技术可让您访问一个 authenticate() 方法类似于Django的AbstractBaseUser类 - 一种依赖于 check_password 函数的方法。但是,您使用所谓的自定义用户模型的身份验证(如上述链接中所概述)的一小段时间...然后将其与自定义后端配对(为了使用电子邮件对于用户名)...由于无法访问典型的authenticate()函数,您遇到麻烦。



例如,像这样...



accounts.models.py




 
#...与postgres,我将子类AbstractBaseUser ...但与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



 
#...是一个自定义后端,甚至需要使用电子邮件进行身份验证而不是用户名?

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导入check_password
从模型导入MyUser

class EmailAuthBackend(object):

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

#...呃,因为我没有使用一个常用的后端与一个预先存在的authenticate()
#方法,没有本机的check_password()功能可用。意味着我必须哈希
#密码等

所以,似乎我有义务写我自己的check_password函数。为了获得通常使用PostgreSQL身份验证发现的 AbstractBaseUser 类所固有的所有优点,我必须完全夸大我的自定义用户模型,这个模型看起来很糟糕,不能很干。我在这里完全搞糊涂了吗?

...即使在使用MongoEngine时,如果我想使用电子邮件而不是用户名进行身份验证,实际上完全不需要使用自定义后端?



我觉得我可能会对Django与MongoEngine在身份验证方面的工作有一个根本的误解,关于我如何建模和调用自定义用户对象/ / Mongolngine的用户对象在这个过程中的特殊子类...



因为 - 现在是 - 我得到一个AnonymousUser '对象在浏览器中没有属性'后端'错误信息。我也注意到,这个问题有时出于意想不到的原因 - 也就是说,authenticate()方法可能会期望一个散列密码,或是因为登录(email)太长了?有关后一种情况可能出现的更多情况,请参阅:



Django注册表单'AnonymousUser'对象没有属性'后台'






settings.py



 
INSTALLED_APPS =(
'django。 contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib。消息',
'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 formAuthBackend
从表单导入AuthenticationForm

def login(request):

form = AuthenticationForm(data = request.POST)
如果form.is_valid ():
try:
backend = EmailAuthBackend()
user = backend.authenticate(email = request.POST ['email'],password = request.POST ['password'])
django_login(请求,用户)
返回重定向('/')
除了DoesNotExist:
返回HttpResponse('用户不存在')
else:
form = AuthenticationForm()

返回render_to_response('accounts / login.html',
{'form':form},
context_instan ce = RequestContext(request))


解决方案

将Django的用户移交给Mongo进行身份验证以开始...通过Twitter获得这个黄金块:



@ blogblimp 我的简短的答案:尽量避免用MongoDB替换Django用户模型。你失去了所有的Django权力,并失去了MongoDB的速度。
认真的,用户涉及到一切,MongoDB并不是关系。

— Daniel Roy Greenfeld(@pydanny) 2014年1月20日





所以:我只是利用PostgreSQL进行身份验证,而Mongo则用于其他对象。这意味着在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 - 如何自定义用户模型/自定义后端的authenticate()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆