Problem with request.user.is_authenticated - python

I am writing a simple django view that takes username and password and authenticates it using authenticate(). However, after successful authentication, request.user.is_authenticated is still False.
Here is the code:
def login(request):
if request.method == 'POST':
form = loginform(request.POST)
if form.is_valid():
username = request.POST['USERNAME']
password = request.POST['PASSWORD']
user = authenticate(username=username, password=password)
if user is not None :
return HttpResponse(request.user.is_authenticated)
else :
return HttpResponse('Login Failed')
else:
form = loginform()
return(render(request,'signup/login.html'))
In my version of django, request.user.is_authenticated is a attribute not function.

from django.contrib.auth import authenticate, login
def login(request):
if request.method == 'POST':
form = loginform(request.POST)
if form.is_valid():
username = request.POST['USERNAME']
password = request.POST['PASSWORD']
user = authenticate(username=username, password=password)
if user is not None :
login(request, user)
return HttpResponse(request.user.is_authenticated)
else :
return HttpResponse('Login Failed')
else:
form = loginform()
return(render(request,'signup/login.html'))
after authenticate don't forget to login user with login(request, user) ,doc is here.

Related

Django authenticate: usage in login vs. register (signup): how do they differ?

I have noticed that the Django authenticate is used in the same way in both the login view and the register view, both return a User object to be used in the login().
In the login view authenticate() uses username and password from the submitted form, then checks on user if the credentials are ok.
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password1']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
The register view looks very similar to the login view. It gets the credentials from the submitted form and uses the user to login.
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(request, username=username, password=password)
login(request, user)
Both call user = authenticate(request, username=username, password=password).
Apart from saving the form in the register view, what is the difference here? Because the login (I guess) is only checking that the credentials are valid, but the register is creating a new user and, since it is creating, the credentials are new data coming in. Am I getting this correctly?
You do not need to authenticate a user in your register method. It can be as simple as,
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
return redirect('<urlname>')
context = {'form': form}
return render(request, '<appname>/<filename>.html', context)
Hence, authentication is only required while logging in as a user. And you can make your login method even simpler by doing this,
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
return redirect('<urlname>')
return render(request, '<appname>/<filename>.html')
Hope this clarifies the situation for you :)

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.

How to fix ERR_TOO_MANY_REDIRECTS?

I'm developing a site on Django, but I got an error ERR_TOO_MANY_REDIRECTS. I think that the matter is in the views.py file. Help figure it out.
P.S. already tried to delete cookie files, it didn't help(
from email import message
from wsgiref.util import request_uri
from django.shortcuts import redirect, render
from django.contrib.auth.models import User, auth
from django.contrib import messages
# Create your views here.
def reg(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
cpassword = request.POST['cpassword']
if password == cpassword:
if User.objects.filter(username=username):
messages.info(request, 'Username taken')
return redirect('registration')
else:
user = User.objects.create_user(username=username, password=password)
user.save()
return redirect('login')
else:
messages.info(request, 'Passwords not matching')
return redirect('registration')
return redirect('/')
else:
return render(request, 'registration.html')
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username = username, password = password)
if user is not None:
auth.login(request, user)
return redirect('/')
else:
messages.info(request, 'Invalid credentials')
return redirect('login')
else:
return render(request, 'login.html')
def logout(request):
auth.logout(request)
return redirect('/')
The problem is coming from your return redirect('/'). Redirect to one of the views written in your urls.py and your problem will be solved.

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 ',]

authenticate() function not working django.contrib.auth

I have a login_page function and in this function the authenticate() function returns a user object only if it is a superuser. For normal user, it returns None. Which is not as the documentation says.
def login_page(request):
if request.user.is_authenticated(): # if user is already logged in
return HttpResponseRedirect('/') # SHOULD BE DASHBOARD
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
seo_specialist = authenticate(username=username, password=password) #returns None
if seo_specialist is not None:
login(request, seo_specialist)
return HttpResponseRedirect('/') # SHOULD BE DASHBOARD
else:
return render(request, 'login.html', {'form': form})
else:
return render(request, 'login.html', {'form': form})
else:
form = LoginForm()
context = {'form': form}
return render(request, 'login.html', context)
Is there anything wrong with my code?
Try this:
def login_page(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
seo_specialist = authenticate(username=username, password=password)
if seo_specialist is not None:
return HttpResponse("Signed in")
else:
return HttpResponse("Not signed in")
else:
# takes you to sign in form.
Basically replace is_valid and cleaned_data with request.POST and then authenticate. Also make sure you have
from django.contrib.auth import authenticate
at the top of your views.
This is from django documentation. You seem to not have passed the request in ...authenticate(request, user...)
This example shows how you might use both authenticate() and login():
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...

Categories

Resources