Django - Login with Email
You should write a custom authentication backend. Something like this will work:
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None
Then, set that backend as your auth backend in your settings:
AUTHENTICATION_BACKENDS = ['path.to.auth.module.EmailBackend']
Updated. Inherit from ModelBackend
as it implements methods like get_user()
already.
See docs here: https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#writing-an-authentication-backend
Django Login with Email or Phone Number
Well, that can be done using by creating a custom user model . I have tested this. It works.
First steps
The first thing you need to do is create a new Django project. Make sure you don't run migrations because there are still a few things we need to do before then.
After creating your new Django project, create a new app called accounts with the following command:
python manage.py startapp accounts
Creating the User Model
By default, the User model provided by Django has a username field, and an email field. However, we also need a phone number field. In order to add this field, we need to extend the Django user model. In the accounts app's models.py file, type in the following code:
models.py
phone_validator = RegexValidator(r"^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$", "The phone number provided is invalid")
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=100, unique=True)
phone_number = models.CharField(max_length=16, validators=[phone_validator], unique=True)
full_name = models.CharField(max_length=30)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
# is_translator = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = ['email', 'full_name']
def __str__(self):
return self.email
@staticmethod
def has_perm(perm, obj=None, **kwargs):
return True
@staticmethod
def has_module_perms(app_label, **kwargs):
return True
@property
def is_staff(self):
return self.is_admin
Register the model with the admin
admin.py
class UserAdmin(BaseUserAdmin):
form = UserChangeForm
add_form = UserCreationForm
list_display = ('email', 'phone_number', 'full_name', 'is_active', 'is_admin')
list_filter = ('is_active', 'is_admin')
fieldsets = (
(None, {'fields': ('full_name', 'email', 'phone_number', 'password')}),
('Permissions', {'fields': ('is_active', 'is_admin', 'is_superuser', 'last_login', 'groups', 'user_permissions')}),
)
add_fieldsets = (
(None, {'fields': ('full_name', 'phone_number', 'email', 'password1', 'password2')}),
)
search_fields = ('email', 'full_name')
ordering = ('email',)
filter_horizontal = ('groups', 'user_permissions')
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
is_superuser = request.user.is_superuser
if is_superuser:
form.base_fields['is_superuser'].disabled = True
return form
admin.site.register(User, UserAdmin)
forms.py
class UserLoginForm(forms.Form):
email = forms.CharField(max_length=50)
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control'}))
for login costumer in login.html
views.py
import random
from .backends import EmailPhoneUsernameAuthenticationBackend as EoP
class UserLoginView(View):
form_class = UserLoginForm
template_name = 'accounts/login.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
return redirect('core:home')
return super().dispatch(request, *args, **kwargs)
def get(self, request):
form = self.form_class
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = EoP.authenticate(request, username=cd['email'], password=cd['password'])
if user is not None:
login(request, user)
messages.success(request, 'You have successfully logged in!', 'success')
return redirect('core:home')
else:
messages.error(request, 'Your email or password is incorrect!', 'danger')
return render(request, self.template_name, {'form': form})
Writing a Custom Backend
backends.py
from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model
from django.db.models import Q
User = get_user_model()
class EmailPhoneUsernameAuthenticationBackend(object):
@staticmethod
def authenticate(request, username=None, password=None):
try:
user = User.objects.get(
Q(phone_number=username) | Q(email=username)
)
except User.DoesNotExist:
return None
if user and check_password(password, user.password):
return user
return None
@staticmethod
def get_user(user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Update the settings (3 Options)
settings.py
INSTALLED_APPS = [
...
# Third-party apps
'accounts.apps.AccountsConfig',
...
]
AUTH_USER_MODEL = 'accounts.User'
AUTHENTICATION_BACKENDS = [
'accounts.backends.EmailPhoneUsernameAuthenticationBackend'
]
I hope your problem will be solved and others will use it.
Unable to log in with email in django
You should use a different authentication backend that checks the credentials with the given user object. Such backend can look like:
# app_name/backend.py
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
UserModel = get_user_model()
class EmailBackend(ModelBackend):
def authenticate(self, request, email=None, password=None):
try:
user = UserModel.objects.get(email=email)
except UserModel.DoesNotExist:
UserModel().set_password(password)
return None
if user is not None and user.check_password(password):
if user.is_active:
return user
return None
Then in the settings file you should use the EmailBackend
for the AUTHENTICATION_BACKENDS
setting [Django-doc]:
# settings.py
# ⋮
AUTHENTICATION_BACKENDS = [
'app_name.backends.EmailBackend'
]
# ⋮
Finally your Form
should make use of the .create_user(…)
method, or work with .set_password()
:
class RegisterForm(forms.ModelForm):
# ⋮
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
Python Django, How I Can use username(uname) or email as a login credentials?
You can work with a Q
object to make a disjunction between email
and uname
:
from django.db.models import Q
if request.method=="POST":
try:
Userdetails=newacc.objects.get(
Q(email=request.POST['email']) | Q(uname=request.POST['email']),
pwd=request.POST['pwd']
)
print("Username=",Userdetails)
request.session[ 'email']=Userdetails.email
return render(request,'Logout.html')
except newacc.DoseNotExist as e:
messages.success(request,' Username / Password Invalid.')
return render(request,'Login.html')
But it seems that your user model does not make use of password hashing. I strongly advise to read the documentation on password management and hash passwords in your user model to prevent hackers from exploiting the passwords stored in the database if they manage to read that. See also this section on Customizing Authentication in Django.
Login with Email and Password in Django
Ohh!! I get it.
It's because I hed to add 'request' parameter in my authentication method.
Right code is given below
backends.py(inside 'account' named app)
class EmailBackend(object):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(email=username)
except User.DoesNotExist:
return None
else:
if user.check_password(password):
return user
else:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Now it is work fine!!
Related Topics
Pandas Dataframe to List of Dictionaries
Iterating Through Directories with Python
Check If a Number Is a Perfect Square
Round to 5 (Or Other Number) in Python
Python Multithreading Wait Till All Threads Finished
How to Convert 'Binary String' to Normal String in Python3
How to Remove Specific Elements in a Numpy Array
How to Switch Position of Two Items in a Python List
What Is the '@=' Symbol for in Python
Difference Between Two Dates in Python
How to Convert a Date String to Different Format
How to Limit Concurrency with Python Asyncio
"Importerror: No Module Named Site" on Windows
Why Does Python Code Use Len() Function Instead of a Length Method