Django Get None After User Authentication - python

def login_page(request):
form = LoginForm(request.POST or None)
context = {
"form" : form
}
print("User logged in")
print(request.user.is_authenticated())
if form.is_valid():
print(form.cleaned_data)
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(request, username = 'username', password = 'password')
print(user)
if user is not None:
print(request.user.is_authenticated())
login(request, user)
# Recirect to a success page.
# context['form'] = LoginForm()
return redirect("/contact")
else:
# Return an 'invalid login' error message.
print("Error")
return render(request, "auth/login.html", context)
I try to create a login page but I get value of 'user' None so I took error everytime. I use Django 1.11.

You are trying to authenticate with constant credentials but need to authenticate with data from form.
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(request, username=username, password=password)
# ^ ^
# changed from 'username' and 'password' to variables
If your user provided wrong credentials, then authenticate return None, since no user can be authenticated with those.

Related

having trouble getting user authentication to work in Python

I am building a django/react app and having trouble with the backend user authentication, have not been able to debug the issue.
After successfully creating an account I am now trying to login. This is the the login route I have built.
#csrf_exempt
#api_view(['POST'])
def loginUser(request):
data = request.data
if request.method == 'POST':
email = data['email']
password = data['password']
try:
user = User.objects.get(email=email)
except:
message = {'detail': 'email does not match a user'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
username = user.username
user = authenticate(request, username=username, password=password)
# Returning correct username and password
print('This is the username:', username)
print('This is the password:', password)
# returning None, even though username and password are matching the info used for signup. (confirmed on admin page)
print('This is the user:', user)
if user is not None:
login(request, user)
serializer = UserSerializer(user, many=False)
message = {'detail': 'user has been logged in'}
return Response(serializer.data)
else:
message = {'detail': 'Username or password is incorrect'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
Any help would be greatly appreciate it since I have been stuck on this for 2 days.
It may be due to the Try-Except or due to the fact that you use email instead of username (but I dont think that matters). You could try something like this:
from django.contrib.auth import authenticate
from django.contrib.auth.models import auth
def loginUser(request):
if request.method == 'POST':
username = request.POST['name']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('index')
else:
messages.info(request, 'Invalid Username or Password')
return redirect('login')
else:
return render(request, 'login.html')
Hopefully this helps.
If you use this code and the problem still persists, it could be that your template or urls may not be correct.

How can I change django login form from username to email when users wanted to login

Is there anyways I can change django custom user login from Username to Email? I have try using this method but it does not work:
def login(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = auth.authenticate(request, email=email, password=password)
if user is not None:
auth.login(request, user)
return redirect('Home')
else:
messages.info(request, 'Invalid Credential')
return redirect('login')
else:
return render(request, 'login.html')
I want to allow user to login using Email not Username.

Django differentiate between incorrect login information and inactive user on login

Currently I added in my site a method for email confirmation when registering. What I saw though, is that when the user is registered, but didn't click in the confirmation link yet and tries to login, I can't differentiate between wrong user/password and not confirmed user.
This is my login function:
def loginUser(request):
if request.user.is_authenticated:
return redirect("decks:index")
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
return redirect("myApp:portal")
elif user is not None:
messages.error(request, "Email is not confirmed.")
else:
messages.error(request, "Invalid username or password.")
else:
messages.error(request, "Invalid username or password.")
form = AuthenticationForm()
return render(request, "myApp/login.html", context = {'login_form': form})
The problem is that when running form.is_valid() the authenticate function from /home/nowork/.local/lib/python3.8/site-packages/django/contrib/auth ModelBackend is executed:
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
So the form.is_valid() will never be true when the is_active flag is False. So I have no way of telling if the combination of user+password is incorrect or the user is not confirmed yet.
I'm not sure what's the correct way of doing this, I thought to do something like:
User.objects.get(username=request.POST['username'])
Can users exploit this somehow? Is there any better way to accomplish this?
Using python3 and Django 4.0
You can make your own CustomLoginBackend as
from django.contrib.auth import get_user_model
class CustomLoginBackend(object):
def authenticate(self, request, username, password):
User = get_user_model()
try:
user = User.objects.using(db_name).get(username=username)
except User.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None
Then in your views.py
def loginUser(request):
if request.user.is_authenticated:
return redirect("decks:index")
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active == True:
login(request, user)
return redirect("myApp:portal")
else:
messages.error(request, "Email is not confirmed.")
else:
messages.error(request, "Invalid username or password.")
else:
messages.error(request, "Invalid username or password.")
form = AuthenticationForm()
return render(request, "myApp/login.html", context = {'login_form': form})
And at last don't forgot to add AUTHENTICATION_BACKENDS in your settings.py as
AUTHENTICATION_BACKENDS = ['path_to_your.CustomLoginBackend ',]

MultiValueDictKeyError at /login/ "u'username'"

I am trying to build a web api for a login page. I keep getting this error. Although i have seen similar and related issues online, the solutions have been of help to me. What am i not doing right?
error
MultiValueDictKeyError at /login/
"u'username'"
login
#csrf_exempt
def my_view(request):
user = request.POST['username']
passcode = request.POST['password']
user = authenticate(request, username=user, password = passcode)
if user is not None:
login(request, user)
return HttpResponse("User logged in")
else:
return HttpResponse("User not found")
updated login
#csrf_exempt
def my_view(request):
if request.method == 'POST':
user = request.POST['username']
passcode = request.POST['password']
user = authenticate(request, username=user, password = passcode)
if user is not None:
login(request, user)
return HttpResponse("User logged in")
else:
return HttpResponse("User not found")
Remove the request parameter from authenticate function,
user = authenticate (username=username, password=passcode)
Edit your view,
#csrf_exempt
def my_view(request):
user = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return HttpResponse("User logged in")
else:
return HttpResponse("User not found")
I just use the request.POST.get('your field_name here')
for example use username = request.POST.get('username') to pick your username

PASSWORD_HASHERS setting in Django

i have an error when ever i try to login by any User
error
Unknown password hashing algorithm 'sahar'. Did you specify it in the
PASSWORD_HASHERS setting?
Views.Py
def Login(request):
state = "Please log in below..."
username = password = ''
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/profile/')
else:
return render_to_response('auth.html',RequestContext(request))
else:
return render_to_response('auth.html',RequestContext(request))
else:
return render_to_response('auth.html',RequestContext(request)
It means there is a plain text 'sahar' stored as the password of the account of a user who tries to log in.
Update the password of the user in Admin or in manage.py shell
user = User.objects.get(username=username)
# use set_password method
user.set_password('sahar')
user.save()
# INSTEAD OF
user.password = 'sahar'
user.save()
Also check your other views to correct the user.password = '...' and User.objects.create(password='...') usages.
This is the best way to save log in details
you can create an object from the form
as
user = form.save(commit=False)
then clean the data to remove any scripts entered in the form fields.
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()

Categories

Resources