0

I wanted to implement login in Django (version 3.1.7) using email instead of username. So I checked for solutions and stumbled upon this question But as a beginner, I don't want play around default user model class by defining custom user model. So a quick fix was to fetch username from user email and then authenticate. My implementation:

from django.shortcuts import render,redirect
from django.contrib.auth.models import User,auth
from django.contrib import messages
def login(request):
if request.method == 'POST':
    email=request.POST['email']
    userinfo= User.objects.filter(email=email)[:1]
    if userinfo.exists():
        username=userinfo.first()
    else:
        messages.info(request,'Email doesn\'t exist..')
        return redirect('login')

    password=request.POST['password']
    user= auth.authenticate(username=username,password=password)
    if user is not None:
        auth.login(request,user)
        return redirect('/')
    else:
        messages.info(request,'Invalid credentials')
        return redirect('login')
else:
    return render(request,'login.html')

I made sure that email is unique while registration:

def register(request):
if request.method == 'POST':
    username=request.POST['username']
    email=request.POST['email']
    password=request.POST['password']
    password1=request.POST['password1']
    if password1 == password:
        if User.objects.filter(username=username).exists():
            messages.info(request,'Username Taken')
            return redirect('register') 
        elif User.objects.filter(email=email).exists():
            messages.info(request,'Email Taken')
            return redirect('register')
        else:
            user= User.objects.create_user(username=username,password=password,email=email)
            user.save()
            return redirect('login')
    else:
        messages.info(request,'passwords not matching')
        return redirect('register')
    
else:
    return render(request,'register.html')

This implementation works correctly. Also, I use csrf_token in both html forms. Now I want to know if there are any security flaws by using these implementation for login. What are the possible ways to make it more stricter. What things will not be achieved correctly by using these approach(if any)?

Akash Dahane
  • 254
  • 2
  • 14

1 Answers1

1

There is one obvious problem with your approach: the uniqueness of your email is only guaranteed as long as you are running only one instance (with only one worker) at a time, which basically limits your application performance to handle one request at a time.

If you try to run multiple workers, you will be faced with a race condition problem: when 2 users are registering the same email address at the same time, it may occur that one users account is created after the availability of the email address was checked by the other one.

In the proper approach, that replaces user model with one that has an email address as a login field, it can be easily fixed by enforcing the uniqueness on the database level.

GwynBleidD
  • 20,081
  • 5
  • 46
  • 77
  • Thank you, this is what I wanted to know. Since, it's college project, I don't need to care about traffic. But in future serious projects your suggestion would be useful. – Akash Dahane Mar 26 '21 at 15:42
  • Having only one worker can have serious performance impact even when a single user tries to access your application. – GwynBleidD Mar 26 '21 at 15:44
  • Sorry I didn't understood what you meant by one worker. Can you further elaborate sir? I want to know more about it – Akash Dahane Mar 27 '21 at 04:25