8๐
You can create separate AuthenticationEmailBackend
just for logging by email and add it to AUTHENTICATION_BACKENDS
in settings. In this way different AUTHENTICATION_BACKENDS
are used as alternatives if authentication fails for previous AUTHENTICATION_BACKENDS
.
app/auth.py
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
class AuthenticationEmailBackend(object):
def authenticate(self, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
settings.py
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
...
"app.auth.AuthenticationEmailBackend",
)
If you leave default django.contrib.auth.backends.ModelBackend
in a list users can login by either username or email.
5๐
Seems request parameter is needed in authenticate method from Django 1.11:
def authenticate(self, request, username=None, password=None)
According to what is said in Django documentation.
- [Django]-Segmentation fault (core dumped) with django-storages
- [Django]-Sublime text 3 Anaconda goto definition not working with Django
- [Django]-Sorl-thumbnail: resize original image before saving?
2๐
A simple backend which allows you to login with either an email address or a username.
It should be combined with another backend for checking permissions:
settings.py:
AUTHENTICATION_BACKENDS = (
'myproject.accounts.backends.EmailOrUsernameModelBackend',
'django.contrib.auth.backends.ModelBackend' )
account/backends.py:
from django.conf import settings
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
if '@' in username:
kwargs = {'email': username}
else:
kwargs = {'username': username}
try:
user = User.objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
and for case-insensitive :
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
# user_model = get_user_model()
if '@' in username:
# kwargs = {'email': username}
field = 'email'
else:
# kwargs = {'username': username}
field = 'username'
try:
case_insensitive_username_field = '{}__iexact'.format(field)
user = User._default_manager.get(**{case_insensitive_username_field: username})
# user = User.objects.get(**kwargs)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
2๐
For Django 3.0:
# myapp/backends.py
from django.contrib.auth.backends import BaseBackend
from .models import MyUser
class EmailAuthenticationBackend(BaseBackend):
def authenticate(self, request, **kwargs):
email = kwargs['username'].lower() # If you made email case insensitive add lower()
password = kwargs['password']
try:
my_user = MyUser.objects.get(email=email)
except MyUser.DoesNotExist:
return None
else:
if my_user.is_active and my_user.check_password(password):
return my_user
return None
def get_user(self, user_id):
try:
return MyUser.objects.get(pk=user_id)
except MyUser.DoesNotExist:
return None
This works for Django 2.0 and probably previous versions:
# myapp/backends.py
from django.contrib.auth.backends import ModelBackend
from .models import MyUser
class EmailAuthenticationBackend(ModelBackend):
def authenticate(self, request, **kwargs):
email = kwargs['username']
password = kwargs['password']
try:
my_user = MyUser.objects.get(email=email)
except MyUser.DoesNotExist:
return None
else:
if my_user.is_active and my_user.check_password(password):
return my_user
return None
(Not sure if it is a good idea to extend the ModelBackend, you can crete your own class)
And then, for both versions:
# settings.py
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"myapp.backends.EmailAuthenticationBackend",
]
- [Django]-Is it possible to include a custom 404 view for a Django app without changing anything at the project level?
- [Django]-Easiest way to write a Python program with access to Django database functionality
- [Django]-Getting task_ids for all tasks created with celery chord
- [Django]-UWSGI async functions don't know about Django's logging settings
0๐
in models.py
class UserDet(models.Model):
email = models.EmailField(max_length=20)
userName = models.CharField(max_length=20)
in views.py
def user_login(request):
response_data={}
if request.session.has_key('login_id'): #If user already logedin send to dashboard else check userid and password
return render(request, '/dashboard.html')
else:
if request.method == 'POST': # If request method is post then only process request
#print('here in login')
try:
username = request.POST.get('username')
password = request.POST.get('pass')
if '@' in username: #check for email
try:
for u in UserDet.objects.filter(email=username):
#username=u['userName']
username=u.userName
except:
response_data['code']=1000
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
if not request.POST.get('rememberme', None): # check user select the remember me or not if yes then create session that expire after long time
#print('seeing it 0')
request.session.set_expiry(0)
user = authenticate(username=username, password=password) # Check user exist or not
if user: #if user exist then
if user.is_active: #check user is active or not if active then successfully loged in else send error
login(request,user)
update_last_login(None, user)
request.session['login_id'] = user.id
response_data['code']=800
response_data['status']='success'
return HttpResponse(json.dumps(response_data), content_type="application/json")
#return render(request, '/dashboard.html')
else:
response_data['code']=900 #Error for User is not active
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
#return HttpResponse("Your account was inactive.")
else: #Error or Invalid username or password
#print("Someone tried to login and failed.")
#print("They used username: {} and password: {}".format(username,password))
response_data['code']=1000
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
except:
response_data['code']=1001
response_data['status']='fail'
return HttpResponse(json.dumps(response_data), content_type="application/json")
else: #Return to index
return redirect('/', {})
- [Django]-Django Serializer returns JSON for parent class objects only and leave child objects as same?
- [Django]-Django user proxy models fast access
- [Django]-Django application not logging request info in production log file when deployed with gunicorn and Nginx
- [Django]-Django Forms for generic relationships. How to include them?
- [Django]-Segmentation fault (core dumped) with django-storages