John Lyon
John Lyon

Reputation: 11440

Can I use django-nonrel and a custom auth backend?

I'm trying to use a custom backend for user authorization with django-nonrel (email adrresses instead of usernames, nothing fancy), and it's just not working. All calls to authenticate() return None. Here is my backend:

from django.contrib.auth.models import User, check_password

    class EmailAuthBackend(object):
        """
        Email Authentication Backend

        Allows a user to sign in using an email/password pair rather than
        a username/password pair.
        """
        supports_anonymous_user = False
        supports_object_permissions = True


        def authenticate(self, email=None, password=None):
            """ Authenticate a user based on email address as the user name. """
            try:
                user = User.objects.get(email=email)
                if user.check_password(password):
                    return user
            except User.DoesNotExist:
                return None

        def get_user(self, user_id):
            """ Get a User object from the user_id. """
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None

And the view (I'm trying to log a user in immediately after they have signed up). new_user is always None:

def create_new_user(request):
    if request.method == 'POST':
        data = request.POST.copy()
        data['username'] = ''.join([choice(letters) for i in xrange(30)])
        data['password'] = data['password1']
        form = CustomUserCreationForm(data)
        if form.is_valid(): 
            user = form.save(commit=False)
            # user must be active for login to work
            user.is_active = True
            user.save() #not sure if this is actually saving
            new_user = authenticate(username=data['username'],\
                    password=data['password'])
            if new_user is None:
                messages.error(request,"God damn it.")
            login(request, new_user)

            messages.info(request, "Thanks for registering! You are\
                                                            now logged in.")
            return render_to_response('invoicer/welcome.html',
                                                     {'user':new_user})

        else:
            messages.error(request, form._errors)
            return HttpResponseRedirect('//')

Can anyone give me some insights as to why my call to authenticate() isn't working?


Edit: Also, When deployed, my signup form is definitely creating users which can be seen in the data viewer on appengine.google.com

Upvotes: 0

Views: 278

Answers (1)

John Lyon
John Lyon

Reputation: 11440

Turns out all I needed to do was change

authenticate(username=email

in the view to:

authenticate(email=email

My backend wasn't being sent an email so it defaulted to none. Shame on me. However, as I'm using the standard django login form, it will pass a named username and password to my backend, so I have to be able to handle both a username (which is actually the user's email address) and email as named keywords.

For now, I'm just doing it like this in my backend:

def authenticate(self, username=None, email=None, password=None):
        """ Authenticate a user based on email address as the user name. """
        if username:
            might_be_email = username
        elif email:
            might_be_email = email

An try to find the user by might_be_email.

Upvotes: 1

Related Questions