1
votes

I was working with a legacy database where there was a table 'tbl_personaldetails', from where i ported data to custome user model. In code to port data from tbl_personaldetails, i use user.set_password(password) which sets password as hash in user table. Trouble is when i try to authenticate(username=username, password=password) where password and username are plain text, authenticate returns None (Even for superuser account from which i can login in admin section).

The code to login is as follows:

class LoginView(FormView):
    form_class = LoginForm
    template_name = 'account/login.html'

    def get_success_url(self):
        return reverse("userHomeAfterLogin")

    def form_valid(self, form):
        email = form.cleaned_data['email'].lower().strip()
        password = form.cleaned_data['password']
        user = authenticate(email=email, password=password)
        if user:
            login(self.request, user)
            return redirect(self.get_success_url())
        else:
            try:
                user = User.objects.get(email__iexact=email)
                if not check_password(password, user.password):
                    form._errors['password'] = ErrorList([u'That is not the correct Password.'])
            except User.DoesNotExist:
                form._errors['email'] = ErrorList([u'This email is not registered with us.'])
            context = self.get_context_data(form=form)
            return self.render_to_response(context)

As of now it flows like this: 1.authenticate returns none, landing up in else part: 2. can retrieve the user with email and check_password is correct. 3. it renders the form w/o any error message

.

what is it that i am doing wrong, everything looks fine though

1

1 Answers

3
votes

As far as I understand from the code snippet, you are using email as your username. With email address, Django's authenticate will never work. It expects username instead. See code below.

def authenticate(**credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend in get_backends():
    try:
        user = backend.authenticate(**credentials)
    except TypeError:
        # This backend doesn't accept these credentials as arguments. Try the next one.
        continue
    if user is None:
        continue
    # Annotate the user object with the path of the backend.
    user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
    return user

In order to use email address as the username field, please refer to http://justcramer.com/2008/08/23/logging-in-with-email-addresses-in-django/.

Hope this helps.