I am trying to create an auth backend to allow my users to log in using either their email address or their username in Django 1.6 with a custom user model. The backend work
Here's a work-around that doesn't require modifying the authentication backend at all.
First, look at the example login view from Django.
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
If authentication with the username fails we can check if there is an email match, get the corresponding username, and try to authenticate again.
from django.contrib.auth import authenticate, login, get_user_model
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is None:
User = get_user_model()
user_queryset = User.objects.all().filter(email__iexact=username)
if user_queryset:
username = user_queryset[0].username
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
Similar to 1bit0fMe's example, email should be a unique field and there is the same (highly unlikely) downside that they mentioned.
I would only recommend this approach if all login on your site is handled by a single view or form. Otherwise, it would be better to modify the authenticate() method itself in the backend to avoid creating multiple points of potential failure.