当前位置: 首页 > 知识库问答 >
问题:

MongoEngine--如何自定义用户模型/自定义后端进行身份验证()

衡安晏
2023-03-14

总结

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

是否有直接(完整)的文档在Django中进行身份验证时,将Mongo用作主数据存储时使用自定义用户对象的示例?(博士后有如此清晰和全面的文档…)

细节

MongoEngine似乎只给你两种认证方式——“经典”(又名“mongoengine.django.auth.MongoEngineBackend”)方式...或者...自定义用户模型(又名“django.contrib.auth.backends.模型后端”)方式——这两种方式在尼古拉斯·科尔托对另一个问题的回答中或多或少都有简洁的概述:

Python-Social al-Auth在mongoEngine(Django)中失败

这两种身份验证技术都允许您访问类似于Django的AbstractBaseUser类的authenticate()方法,该方法依赖于check_password函数。但是,当您使用所谓的“自定义用户模型”风格的身份验证时(如上链接所述)。。。然后将其与自定义后端配对(以便将电子邮件用于用户名)。。。由于无法访问典型的authenticate()函数,您会遇到麻烦。

例如,像这样。。。

# ...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 = '' ...
# ...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.

所以,看起来,我不得不编写自己的check_密码函数。要获得AbstractBaseUser类固有的所有优点,通常可以通过PostgreSQL身份验证找到,我必须完全扩展我的自定义用户模型,它看起来很粗糙,不会很枯燥。

我在这里完全糊涂了吗。。。i、 例如,如果我想在使用MongoEngine时使用电子邮件而不是用户名进行身份验证,那么实际上完全没有必要使用自定义后端吗?

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

因为——就像现在一样——我在浏览器中收到一条“AnonymousUser”对象没有“backend”属性的错误消息。我还注意到,这个问题有时是由于意外的原因而存在的——也就是说,authenticate()方法可能需要哈希密码,或者是因为登录(电子邮件)太长。。。?有关后一种情况可能出现的更多情况,请参阅:

Django注册表表单“AnonymousUser”对象没有“backend”属性

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

共有2个答案

钮兴安
2023-03-14

也许我有点晚了,但我可以使用mongoengine用户django authenticate完成电子邮件身份验证任务,以下是我的工作方式:

from django.contrib.auth import authenticate, login as do_login, logout as do_logout

def login(request):

    data = extractDataFromPost(request)
    email = data["email"]
    password = data["password"]

    try: 
        user = User.objects.get(username=email)
        if user.check_password(password):
            user.backend = 'mongoengine.django.auth.MongoEngineBackend'
            user = authenticate(username=email, password=password)
            do_login(request, user)
            request.session.set_expiry(3600000) # 1 hour timeout
            return jsonResponse(serializeUser(user)) 
        else:
            result = {'error':True, 'message':'Invalid credentials'}
            return jsonResponse(result) 
    except User.DoesNotExist:
        result = {'error':True, 'message':'Invalid credentials'}
        return jsonResponse(result)
勾裕
2023-03-14

好吧,看起来最好的做法不是首先将Django的用户交给Mongo进行身份验证。。。通过推特获得了这个金块:

@blogblimp我的简短回答:尽量避免用MongoDB替换Django用户模型。你失去了所有的Django力量,失去了MongoDB的速度。说真的,用户与一切都相关,MongoDB不是关系的。


所以:我将利用PostgreSQL进行身份验证,利用Mongo进行其他对象。这意味着在Django设置中命名/连接两个数据库。回想起来,我想其中的寓意是:永远不要因为Mongo很酷就使用它。Mongo仍然是Django世界的二等公民。

 类似资料:
  • 我想要自定义firebase身份验证,其中用户管理下级用户的角色。我需要指导,了解如何实现自己的后端身份验证系统。文档中到处都提到“将用户名和密码发送到后端以生成自定义令牌”。这个后端是什么?我在哪里追求这个?我的知识领域是firebase,firebase functions,angular 2/4,ionic2,用于本次讨论。。。谢谢

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 在过去的几周里,我一直在努力掌握KeyClope,这样我就可以实现一种使用遗留提供商(基于Oracle,带有会话表和各种奇怪的东西)对用户进行身份验证的方法。我们计划在不久的将来解决这个问题,但目前我们必须解决这个问题,所以我们的想法是在前线使用KeyClope——利用它提供的主要好处,比如SSO——在需要身份验证的应用程序中省略传统的身份验证提供程序。 我读了一些关于构建自定义OIDC身份提供程

  • 问题内容: 我可以使用Google帐户在AppEngine中对用户进行身份验证的方式非常好。 但是,我需要使用 自定义的身份验证登录系统 。 我将有一个AppUsers表,其中包含用户名和加密密码。 我阅读了有关gae会话的内容,但在启动应用安全性方面需要帮助。 如何跟踪经过身份验证的用户会话?设置cookie? 初学者。 问题答案: 您可以使用cookie来做到这一点……其实并不难。您可以使用C

  • 我在spring MVC项目中实现了一个自定义身份验证提供程序。在我自己的重载authenticate()方法中,我实现了自己的身份验证,其中我构造了自己的UserPasswordAuthenticationToken()并返回对象。 现在,上述对象“UserPasswordAuthentictionToken”中的用户ID被匿名化,密码为null,权限设置为授予该用户的权限。 问题: 这是否会导

  • 同时尝试Spring启动、安全性和数据。 我刚刚遇到了这种情况: 我在内存数据库中使用H2,并在启动时用liquibase和一个用户用用户名和密码对其进行加密。 现在我想让Spring Security性根据H2进行身份验证。为此,我有以下代码: 并且我实现了如下userDetails: 但我的测试一直失败 身份验证不应为空 尝试登录会给我 凭据错误 要使UserDetailsService的自定