Question

I'm trying to implement a custom authentication backend in Django that will log users in based on a unique id from a third-party service (Facebook, LinkedIn, etc.) Basically, once users OAuth to the third-party service and get a unique identifier back, I want to log them in seamlessly.

But my custom backend doesn't work and returns `None.'

Here's my custom backend:

from myapp.models import Account
from django.contrib.auth.models import User

class ThirdPartyServiceBackend(object):

    def authenticate(self,acct_id=None):
        if acct_id is not None:
            try:
                return User.objects.get(account__uniq_id=acct_id)
            except:
                return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

I've enabled this backend in my settings.py:

AUTHENTICATION_BACKENDS = (
    'myproject.myapp.backends.ThirdPartyServiceBackend',
    'django.contrib.auth.backends.ModelBackend',
)

And this is how I process it in views.py:

# oauth processing and everything goes here
try:
    # login and redirect to search page

    user = authenticate(acct_id=third_party_service_user_info['id'])

    if user is not None:
        auth_login(request,user)
        return HttpResponseRedirect('/')

This calls work in the shell no problem -- user is returned. But the authenticate call is failing -- any ideas on what I'm doing wrong?

Was it helpful?

Solution

From Django docs:

Once a user has authenticated, Django stores which backend was used to authenticate the user in the user's session, and re-uses the same backend for the duration of that session whenever access to the currently authenticated user is needed. This effectively means that authentication sources are cached on a per-session basis, so if you change AUTHENTICATION_BACKENDS, you'll need to clear out session data if you need to force users to re-authenticate using different methods. A simple way to do that is simply to execute Session.objects.all().delete().

Try that, I had the same problem and that was my fix.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top