【问题标题】:using request.user.is_authenticated() in Django project在 Django 项目中使用 request.user.is_authenticated()
【发布时间】:2012-06-04 07:26:31
【问题描述】:

当我尝试执行 request.user.is_authenticated() 时,我得到一个 ValidationError: None is not a valid ObjectId

我正在尝试追查问题,但我不知道是什么原因造成的。我正在使用 MongoEngine(和 MongoDB)。

我的 settings.py 中有以下内容:

AUTHENTICATION_BACKENDS = (
    'mongoengine.django.auth.MongoEngineBackend',
    'rs.claimutil.auth_backend.ClaimAuthBackend',
)


SESSION_ENGINE = 'mongoengine.django.sessions'

这是我得到的:

追溯:文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py” 在 get_response 111. response = callback(request, *callback_args, **callback_kwargs) 保留文件“/Users/bastiano/Documents/ttsf/rsrv/views.py” 11.如果不是request.user.is_authenticated():文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py” 在内部 184. self._setup() 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py” 在 _setup 248. self._wrapped = self._setupfunc() 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/middleware.py” 在 16. request.user = SimpleLazyObject(lambda: get_user(request)) 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/middleware.py” 在 get_user 8. request._cached_user = auth.get_user(request) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/init.py" 在 get_user 101. user = backend.get_user(user_id) or AnonymousUser() 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/django/auth.py” 在 get_user 149.返回User.objects.with_id(user_id)文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 with_id 923.返回self.filter(pk=object_id).first()文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在第一 843. 结果 = self[0] 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 getitem 中 1136. 返回 self._document._from_son(self._cursor[key]) 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 _cursor 中 579. self._cursor_obj = self._collection.find(self._query,文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 _query 375. self._mongo_query = self._query_obj.to_query(self._document) 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 to_query 202. query = query.accept(QueryCompilerVisitor(document)) 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在接受 267.返回visitor.visit_query(self)文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在访问查询中 159. 返回 QuerySet._transform_query(self.document, **query.query) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py” 在 _transform_query 720. value = field.prepare_query_value(op, value) 文件 “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py” 在prepare_query_value 455. 返回 self.to_mongo(value) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py” 在 to_mongo 451. self.error(unicode(e)) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py” 错误 203. raise ValidationError(message, errors=errors, field_name=field_name)

异常类型:/rs/claim 处的 ValidationError 异常值:无 不是有效的 ObjectId

任何想法为什么会发生这种情况?有没有更简单的方法在 Django + MongoDB 中进行用户身份验证?

Views.py:

def claim(request):
    if request.method == 'GET':
        if not request.user.is_authenticated():
            return shortcuts.redirect('rs/login')
        all_b = dbutil.get_b(all=True)
        return shortcuts.render_to_response('rs/index.html',
                                             {'all_b':all_b},
                                            context_instance=template.RequestContext(request))
    elif request.method == 'POST':

为简单起见,省略了视图的其余部分。我用 ipdb 调试它,if not request.user.is_authenticated() 是问题所在。我之前尝试过使用django.contrib.auth.decorators.login_required.decorator,但也失败了。

【问题讨论】:

  • 问题是 Django 使用的是mongoengine.django.auth.MongoEngineBackend而不是我创建的身份验证后端。尽管我在 settings.py 中指定了它,但我的一个视图中有以下行:r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend',这当然会强制 Django 使用该身份验证后端。 @Ross 和 @okm,谢谢!

标签: python django mongodb django-authentication mongoengine


【解决方案1】:

尝试将您的mongoengine 更新到最新版本。 In master,是

def get_user(userid):
    """Returns a User object from an id (User.id). Django's equivalent takes
    request, but taking an id instead leaves it up to the developer to store
    the id in any way they want (session, signed cookie, etc.)
    """
    # your installed mongoengine might not include following two lines
    if not userid:
        return AnonymousUser()
    return MongoEngineBackend().get_user(userid) or AnonymousUser()

根据引用,带有None 值的userid 会导致问题。

【讨论】:

  • 我有最新的 mongoengine。我在get_user(userid)get_user(self, userid) 上都设置了跟踪,它实际上使用了后者——它是MongoEngineBackendclass 的一部分。我认为 Django 应该使用我定义的身份验证后端。即使我在设置中注释掉 MongoEngineBackend,Django 仍然使用 MongoEngineBackend。
  • @Bastiano9 使用的后端信息存储在会话中,因此注释掉的MongoEngineBackend 对保存的会话无效。二、get_user(userid)userid的值是多少?
  • 我删除了存储在数据库中的所有会话并重新启动了服务器。我解决了这个问题。在我的一个观点中,我有以下几点:r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend',这就是为什么它从不使用我的自定义身份验证后端。
【解决方案2】:

你使用的是什么版本的 MongoEngine / Django?

您是否启用了django.contrib.auth.middleware.AuthenticationMiddleware?这应该为请求设置一个User 实例或AnonymousUser

rs.claimutil.auth_backend.ClaimAuthBackend 是什么样的?它的get_user 方法返回什么?如果您只有一个身份验证后端,它会停止出错吗?

【讨论】:

  • 您是否启用了django.contrib.auth.middleware.AuthenticationMiddleware? - 是的。我在 auth_backend.ClaimAuthBackend 中注释掉了 MongoEngine 后端并在 authenticate()get_user() 上设置了 import ipdb; ipdb.set_trace(),而 Django 完全跳过了这个后端。
  • 所以即使没有安装 Mongoengine 作为后端,ClaimAuthBackend 也会被跳过?
  • 还有什么版本? mongoengine / django的
  • 我发现了问题所在。请参阅@okm 答案下方的评论。非常感谢您的出色指点!
【解决方案3】:

在我的一个观点中,我有以下几点: r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend',这就是 Django 忽略 settings.py 中的 AUTHENTICATION_BACKENDS 并且从未使用我的自定义身份验证后端的原因。

【讨论】:

    猜你喜欢
    • 2017-01-18
    • 2019-04-15
    • 2015-12-04
    • 1970-01-01
    • 2019-01-19
    • 2021-02-12
    • 2012-02-18
    • 2012-04-06
    • 2016-09-28
    相关资源
    最近更新 更多