Restricting registrations only to specific users in Django
Abenezer Belachew · November 02, 2021
2 min read
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.