Django request doesn't save the logged in user - python

So I'm starting to learn Django authentication.
from django.contrib.auth import login as log_in
def login(request):
...
if request.method == "POST":
form = UserLoginForm(request.POST)
if form.is_valid():
user = User.objects.filter(email=form.cleaned_data["email"])
if user.exists():
user = user.first()
if check_password(
form.cleaned_data["password"], user.password
):
log_in(request,user)
return redirect("/main/")
else:
messages.warning(request, "email/password are incorrect")
else:
messages.warning(request, "User not found")
...
and I'm trying to access the request.user in another view like this:
if request.user.is_authenticated:
#do somthing
but while debugging I found that after the first code log_in() statement the request.user is authenticated, but in the seconed code it's not.

You have to set the authentication backend:
from django.conf import settings
# ...
user.backend = settings.AUTHENTICATION_BACKENDS[0]
log_in(request, user)

I found the problem,
The problem is that I'm using a custom user model with an email attribute instead of a username so I had to build a new Backend to use with my custom model, then added it to the AUTHENTICATION_BACKENDS in the settings.py file.
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import check_password
from .models import User
class NewBackend(ModelBackend):
def authenticate(self, request, email, password) -> User:
try:
user: User = User.objects.get(email=email)
if user.check_password(password):
return user
else:
return None
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 in views.py
def login(request: HttpRequest):
if request.user.is_authenticated:
return redirect("/main/")
if request.method == "POST":
form = UserLoginForm(request.POST)
if form.is_valid():
umail=form.cleaned_data['email']
upasswd=form.cleaned_data['password']
user = authenticate(request=request,email=umail,password=upasswd)
if user is not None:
log_in(request,user)
return redirect("/main/")
else:
messages.warning(request, "email/password are incorrect")
form = UserLoginForm()
context = {"title": "Login", "form": form}
return render(request, "login.html", context)
settings.py:
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'login_signup.backend.NewBackend',
]

Related

Django Authentication to use both email and username in exiting app

I am struggling with adding custom AUTHENTICATION_BACKENDS for my exiting app. I have all done with my app but now want to login with username or EmailID. I am successfully able to login with username and password.
now just want to add EmailID as well.
I tried adding below code in my settings.py
AUTHENTICATION_BACKENDS = ( 'authentication.backends.EmailOrUsernameModelBackend', 'django.contrib.auth.backends.ModelBackend', )
and in \authentication\backends.py I have
from django.conf import settings
from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
print("Inside EmailorUsernameModelBackend")
if '#' in username:
print("User with Email")
kwargs = {'email': username}
else:
print("User with Username")
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
where my \authentication\views.py
def login_view(request):
form = LoginForm(request.POST or None)
msg = None
if request.method == "POST":
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
print("User=",user)
if user is not None:
login(request, user)
return redirect("dashboard")
else:
msg = 'Invalid credentials'
else:
msg = 'Error validating the form'
return render(request, "/login.html", {"form": form, "msg": msg})
I am trying to print some statement if authenticate method call from EmailOrUsernameModelBackend but none printing, so I guess for some reason it is not calling that method.
please help me what I am missing to call custom authenticate method.
I think the issue is that you're not subclassing BaseBackend from Django, but just the regular python object.
I usually do 2 seperate backends, that makes my code a lot clearer to read for others.
from django.contrib.auth.backends import BaseBackend
class EmailBackend(BaseBackend):
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
class UsernameBackend(BaseBackend):
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(username=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None

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.

Why doesn't my form validation work in django?

I am trying to have user validation in my django social media/blog app. I do not understand why this code does not work. The problem: No matter what name I type in the form it says the user does not exist even though the user does in fact exist. Any help would be amazing.
from django.shortcuts import render, redirect
from sign_in.forms import SignInForm
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth.forms import forms
from django.http import HttpResponseRedirect
def sign_in(request):
if request.method == "POST":
form = SignInForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = User.objects.filter(username=username, password=password)
if user.exists():
return HttpResponseRedirect("boom/")
else:
messages.error(request, f"User {user} does not exist.")
else:
form = SignInForm()
return render(request, "sign_in/sign_in.html", {"form": form})
this is not how Django authentication works.
https://docs.djangoproject.com/en/3.1/topics/auth/
use authenticate method
try this
from django.contrib.auth import login, authenticate
def sign_in(request):
if request.method == "POST":
form = SignInForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
login(request, user)
if user.exists():
return HttpResponseRedirect("boom/")
else:
messages.error(request, f"User {user} does not exist.")
else:
form = SignInForm()
return render(request, "sign_in/sign_in.html", {"form": form})

User can't authenticate

I am using custom authentication with custom user model.
When user authenticates it redirects to the home page, as needed, but the user does not get authenticated.
And when I check in a template {{user.is_authenticated}} it says False.
How to fix that?
Here is my backend file for custom authentication:
from contracts.models import User
from django.contrib.auth.hashers import check_password
class AuthBackend:
def authenticate(self, email=None, password=None):
try:
user = User.objects.get(email=email)
if not check_password(password, user.password):
return None
except User.DoesNotExist:
return None
return user
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
my view:
class LoginView(View):
form_class = LoginForm
template_name = 'login.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(email=email, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('/')
return render(request, self.template_name, {'form': form})
Added to my setting file:
AUTHENTICATION_BACKENDS = ['contracts.auth.backend.AuthBackend']
AUTH_USER_MODEL = 'contracts.User'
Django version is 2.0.4
I fixed it when I changed my login import:
from django.contrib.auth.views import login
to:
from django.contrib.auth import login

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