Restricting registrations only to specific users in Django

Abenezer Belachew

Abenezer Belachew · November 02, 2021

2 min read

Bouncer

Say you're building an authentication system where you want to only allow users who have emails that end in a specific domain to register. For example, we may only want people with a gmail account to register. To achieve this, we can use the clean_<fieldname>() method on our form subclass. In this case since, since we are 'cleaning' the email, we'll use the clean_email method available for user creation forms.

An idea that I first thought of was to check if the email provided ended with 'gmail.com' like the code provided below.

def clean_email(self, email):
        """
        Check if the email ends with gmail.com
        """
        acceptable_domains = ('gmail.com',)
        if email.endswith(acceptable_domains):
            return email
        else:
            raise forms.ValidationError('Please use your gmail account to register')
  • This may sound like a good idea but it is susceptible to email addresses with domain names that end with gmail.com but are not necessarily provided by google. E.g. user@thisisnotgmail.com.

  • Here are some possible solutions that make use of the fact that the '@' symbol can not be present in the first part of an email address (the recipient's name). [source]

Using index and slicing

def clean_email(self, email):
        """
        Check if the email ends with gmail.com
        """
        acceptable_domains = ['gmail.com',]
        domain = email[email.index('@') + 1 : ]
        if domain in acceptable_domains:
            return email
        else:
            raise forms.ValidationError('Please use your gmail account to register')

Using split

def clean_email(self, email):
        """
        Check if the email ends with gmail.com
        """
        acceptable_domains = ['gmail.com',]
        domain = email.split('@')[1]
        if domain in acceptable_domains:
            return email
        else:
            raise forms.ValidationError('Please use your gmail account to register')

Using urllib.parse

from urllib import parse
...
def clean_email(self, email):
        """
        Check if the email ends with gmail.com
        """
        acceptable_domains = ['gmail.com',]
        domain = parse.urlparse(email).path
        if domain in acceptable_domains:
            return email
        else:
            raise forms.ValidationError('Please use your gmail account to register')

Using regular expressions

import re
...
def clean_email(self, email):
        """
        Check if the email ends with gmail.com
        """
        acceptable_domains = ['gmail.com',]
        domain = re.search('@.*', email2).group()[1:]
        if domain in acceptable_domains:
            return email
        else:
            raise forms.ValidationError('Please use your gmail account to register')
  • If there is a need to add more domain names, you can simply add it to the acceptable_domains array.