Django : request.user not set after redirect - django

Specifically, after authentication and redirect, request.user is an anonymous user.
login (view function)
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
#django.contrib.auth.login
Login(request, form.get_user())
str = reverse('cm_base.views.index')
return HttpResponseRedirect(str)
else:
# Their password / email combination must have been incorrect
pass
else:
form = LoginForm()
return render_to_response('cm_base/login.html',
{"DEBUG": True,
'form' : form
},
context_instance=RequestContext(request))
in the index view, I removed the login_required decorator and tested the request.user object
def index(request):
test = request.user.is_authenticated()
return render_to_response('cm_base/index.html',
{"DEBUG": True,
"user": request.user,},
context_instance=RequestContext(request))
Test returns false.
Fix
I ended up just calling the index view directly. I am still confused as to why the user object was lost when I called HttpResponseRedirect.
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST) # Not shown in this example
if form.is_valid():
Login(request, form.get_user())
str = reverse('cm_base.views.index')
return index(request)
else:
# Their password / email combination must have been incorrect
pass
else:
form = LoginForm()

A lot of things going on here that shouldn't be. First, you don't need to pass request.user, its available by default as long as you are using RequestContext, which you are.
Login() this method, what exactly is it doing? Django provides a built-in login method that you should be using if you are using the default authentication backend.
You are also not checking if a user is enabled or disabled.
Here is a different version of your code, adapted from the example in the documentation:
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
def login_view(request):
form = LoginForm(request.POST or {})
ctx = {'form': form}
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username, password)
if not user:
ctx['errors'] = 'Invalid Login'
return render(request, 'login.html', ctx)
if not user.is_active:
ctx['errors'] = 'User is locked'
return render(request, 'login.html', ctx)
login(request, user)
return redirect('home')
else:
return render(request, 'login.html', ctx)

What auth backend are you using? If it is something other than the ModelBackend make sure your get_user method is correct. It sounds as if the auth middleware is sending a different identifier (like the pk instead of a username) than the one you are looking for in your get_user method.

This was the fix
<link rel="icon" href="{{ STATIC_URL }}img/favicon.ico" />
This file was missing from the static directory. The resulting 404 was breaking the user session.

Related

Django request.user become AnonymousUser after redirect

The problem here is that request.user always turn to AnonymousUser after redirect.
I'm writing my own login method and authentication backend because I'm not using password for login.
Here's my code.
#app/view.py
def login(request):
template = 'index.html'
if request.method == "POST":
userId = request.POST.get('userId', '')
displayName = request.POST.get('displayName', '')
user = auth.authenticate(userId=userId, displayName=displayName)
if user.is_authenticated:
auth.login(request, user)
return redirect('home') ##### if change to "render(request, template, locals())", will see request.user as logged in user #####
else:
return render(request, template, locals())
else:
return HttpResponse('')
def home(request):
template = 'index.html'
user = request.user
return render(request, template, locals())
I'm checking whether the request.user is logged in by javascript. If not, use a post function to /login/ URI. The liff.getProfile() is my third party javascript function to get userId and displayName from profile.
#html.javascript
DjangoLogin="{{request.user}}";
if (DjangoLogin=="AnonymousUser"){
liff.getProfile().then(function(profile) {
userId = profile.userId;
displayName = profile.displayName;
post('/login/',{ 'userId': userId, 'displayName': displayName, 'csrfmiddlewaretoken': '{{ csrf_token }}'});
});

Django.contrib.auth.login is not working after i redirect to a different url

The login function is not working , after i call login , authenticated is set 'true' but after i redirect to 'main' view authenticated is set 'false'. How to keep the user logged in even after redirection?
class LoginForm(forms.Form):
user = forms.CharField()
password = forms.CharField()
def login(self):
try:
cred = users.objects.get(username = user)
if password==cred.password):
return (True, cred)
return (False, 'Invalid Password.')
except:
return (False, 'Not exist')
from django.contrib.auth import login as auth_login
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
valid, message = form.login()
if valid:
auth_login(request, message)
print(request.user.is_authenticated)
# this is not working
return redirect(main)
else:
return redirect(login)
form = LoginForm()
args = {'form': form}
return render(request, 'accounts/login.html', args)
def main(request):
print(request.user.is_authenticated)
You shouldn't write check your user credentials in form class. Do it in your login view. Example:
# views.py
from django.contrib.auth import authenticate, login
from django.urls import reverse
from django.shortcuts import redirect, render
def login_view(request): #changed_the name shouldn't be login
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username, password)
if user:
login(user)
return redirect(reverse("main"))
else:
return redirect(reverse("login"))
form = LoginForm()
args = {"form": form}
return render(request, 'accounts/login.html', args)
# urls.py
urlpatterns = [
path("login/", views.login_view, name="login"), # <-- really important
path("main/", views.main_view, name="main")
]
To summarize - to redirect to another page use redirect function. If you set name parameter in url of you view, you can reffer to this view using reverse. Also don't reinvent the wheel and write your own authentication function. Django provides: authenticate(username, password) and login(user) function.

How to modify my login to verify email?

I have already used login class
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
And views file of my app
from .forms import LoginForm
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'],password=cd['password'])
if user.is_active:
login(request, user)
return HttpResponse('Authenticated!')
else:
return HttpResponse('Disabled account')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})
(hunter) provides email verifier.This is HTTP request example
GET https://api.hunter.io/v2/email-verifier?email=steli#close.io
How to modify my login and views files?
Try to use the code below :
import urllib2
get_request = urllib2.urlopen('https://api.hunter.io/v2/email-verifier?email=' + username)
then the get_request variable will contain a JSON object as mentioned in hunter documentation.
the get_request will be added in after the cd = form.cleaned_data

Change Password Django

I have the following functions to change a password and display the users profile, but upon submitting the form instead of being redirected to the 'profile/' page I get an error saying The view core.views.change_password didn't return an HttpResponse object. It returned None instead., why is this?
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
def change_password(request):
if request.method == "POST":
form = PasswordChangeForm(data= request.POST, user = request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user) #this function keeps the user logged in afte they change their password
# request.user could not have been passed in because that would pass in 'AnonymousUser', however
#form.user gets the user who was filling in the form and passes it to the function
return redirect('/profile')
else:
form = PasswordChangeForm(user = request.user)
args = {'form': form} # gives access to the form in the template
return render(request, 'core/change_password.html', args)
def view_profile(request):
args = {'user': request.user} #
return render(request, 'core/profile.html', args)
Note: The profile page does work on other parts of the site, for example after logging in the user is redirected to their profile page with no issue.
You should move the last two lines out of the else block. This way, you will return a response for POST requests when the form is not valid.
def change_password(request):
if request.method == "POST":
form = PasswordChangeForm(data= request.POST, user = request.user)
if form.is_valid():
...
return redirect('/profile')
else:
form = PasswordChangeForm(user = request.user)
args = {'form': form} # gives access to the form in the template
return render(request, 'core/change_password.html', args)

Redirect to home as a logged in user after successful registration

I have a custom User model (MyUser), and a registering form (UserCreationForm) for that model. After registering the user I want it to redirect to the homepage. It is however redirecting to the homepage, but the problem is that the user is not logged in even after login() function is used in the register view, and so it is redirected back to the login page.
views.py:
#login_required(login_url='/account/login/')
def home(request):
return render(request, 'home.html')
def login_view(request):
form = LoginForm(request.POST or None)
if request.POST and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return redirect("/")# Redirect to a success page.
return render(request, 'login.html', {'form': form })
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect("/")
else:
form = UserCreationForm()
return render(request, 'register.html', {
'form': form
})
Its giving me an error:
AttributeError at /account/register/
'MyUser' object has no attribute 'backend'
What am I doing wrong here? Please help me how to solve this. Thank you.
Maybe, this can solve your problem.
This will authenticate and login the user after registration.
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
password = self.request.POST.get('password', None)
authenticated = authenticate(
username=user.username,
password=password
)
if authenticated:
login(request, authenticated)
return redirect("/")
else:
form = UserCreationForm()
return render(request, 'register.html', {
'form': form
})