1

When I try to do request.user.is_authenticated() I get a ValidationError: None is not a valid ObjectId

I'm trying to track down the problem but I do not what's causing it.I'm using MongoEngine (and MongoDB.)

I have the following in my settings.py:

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


SESSION_ENGINE = 'mongoengine.django.sessions'

This is what I get:

Traceback: File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 111. response = callback(request, *callback_args, **callback_kwargs) File "/Users/bastiano/Documents/ttsf/rsrv/views.py" in reserve 11. if not request.user.is_authenticated(): File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py" in inner 184. self._setup() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/functional.py" in _setup 248. self._wrapped = self._setupfunc() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/middleware.py" in 16. request.user = SimpleLazyObject(lambda: get_user(request)) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/middleware.py" in 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" in get_user 101. user = backend.get_user(user_id) or AnonymousUser() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/django/auth.py" in get_user 149. return User.objects.with_id(user_id) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in with_id 923. return self.filter(pk=object_id).first() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in first 843. result = self[0] File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in getitem 1136. return self._document._from_son(self._cursor[key]) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in _cursor 579. self._cursor_obj = self._collection.find(self._query, File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in _query 375. self._mongo_query = self._query_obj.to_query(self._document) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in to_query 202. query = query.accept(QueryCompilerVisitor(document)) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in accept 267. return visitor.visit_query(self) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in visit_query 159. return QuerySet._transform_query(self.document, **query.query) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/queryset.py" in _transform_query 720. value = field.prepare_query_value(op, value) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py" in prepare_query_value 455. return self.to_mongo(value) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py" in to_mongo 451. self.error(unicode(e)) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/mongoengine/base.py" in error 203. raise ValidationError(message, errors=errors, field_name=field_name)

Exception Type: ValidationError at /rs/claim Exception Value: None is not a valid ObjectId

Any ideas why this is happening? Is there an easier way to do user authentication in 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':

The rest of the view is omitted for simplicity. I used ipdb to debug it and if not request.user.is_authenticated() is the problem. I tried using django.contrib.auth.decorators.login_required.decorator before, but it, too, failed.

1
  • The problem was that Django was using mongoengine.django.auth.MongoEngineBackendand not the authentication backend I created. Even though I specified it in settings.py, I had the following line in one of my views: r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend', this, of course, forces Django to use that authentication backend. @Ross and @okm, thank you! Commented May 30, 2012 at 15:19

3 Answers 3

2

Try to update your mongoengine to the latest version. In master, it is

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

A userid w/ value of None causes the problem, according to the trackback.

Sign up to request clarification or add additional context in comments.

3 Comments

I have the latest mongoengine. I set a trace on both get_user(userid)and get_user(self, userid) and its actually using the latter - which is part of the MongoEngineBackendclass. I thought Django was supposed to use the authentication backend I defined. Even when I comment out MongoEngineBackend in my settings, Django still uses MongoEngineBackend.
@Bastiano9 the info of the used backend is stored in session, thus commented out MongoEngineBackend would not have effect for a saved session. Second, what's the value of userid in the get_user(userid)?
I got rid of all the sessions stored in the db and restarted the server. I figured out the problem. In one of my views I had the following: r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend', which is why it was never using my custom authentication backend.
1

What version of MongoEngine / Django are you using?

Have you enabled the django.contrib.auth.middleware.AuthenticationMiddleware? That should set a User instance or AnonymousUser to the request.

What does rs.claimutil.auth_backend.ClaimAuthBackend look like? And what does its get_user method return? Does it stop erroring if you just have one authentication backend?

4 Comments

Have you enabled the django.contrib.auth.middleware.AuthenticationMiddleware? - Yes. I commented out the MongoEngine backend and set an import ipdb; ipdb.set_trace()on both authenticate() and get_user() in auth_backend.ClaimAuthBackend and Django is completely skipping this backend.
so ClaimAuthBackend is skipped even without Mongoengine installed as a backend?
Also what versions? of mongoengine / django
I figured out the problem. See the comment below @okm's answer. Thank you so much for the excellent pointers though!
1

In one of my views I had the following: r_v.obj.backend = 'mongoengine.django.auth.MongoEngineBackend', which is why Django was ignoring the AUTHENTICATION_BACKENDS in settings.py, and was never using my custom authentication backend.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.