Django authentication stops working when I add a logout function - django

I made this simple Django site which justs logs a user in:
def main(request):
# User is already logged in and redirected to main
if request.user.is_authenticated():
return render(request, 'mysite/main.html')
# User is attempting to log in
elif 'username' in request.POST:
return login(request)
# Return login page
return render(request, 'mysite/login.html')
def login(request):
username = request.POST.get('username')
password = request.POST.get('password')
logged_in = authenticate(username=username, password=password)
if logged_in is not None:
return render(request, 'mysite/main.html')
else:
return render(request, 'mysite/login.html')
All of this worked without any problems. I could refresh the page and I was still logged in, and '{{ request.user.username }}' in main.html worked as intended. Then I added a way to log out. It's just a link in main.html, pointing to logout/, which points to this view:
def log_out(request):
print "logging out"
logout(request)
return HttpResponseRedirect('/')
After I had logged out for the first time, the authentication stopped working properly. I can still log in if I enter the correct username and password, but '{{ request.user.username }}' doesn't output anything anymore, and if I refresh the page while at main.html I now end up at login.html.
Why is this happening? Why is the authentication ruined by me logging out once?

The addition of logout is not to blame here. You are missing an important step in the login process: you don't call auth.login().
authenticate() only returns an authenticated user; you still need to log that user in.

Related

how do i disable browser back button after login?

def login(request):
if request.session.has_key('is_logged'):
return redirect('/')
if request.method == 'POST':
email = request.POST['email']
psw = request.POST['psw']
user = auth.authenticate(username=email, password=psw)
if user is not None:
auth.login(request, user)
request.session['is_logged'] = True
return redirect('/')
else:
messages.info(request, 'invalid user name or password')
return redirect('login')
else:
return render(request, 'login.html')
def logout(request):
auth.logout(request)
return redirect('/')
how do i disable browser back button after login? is it good idea to disable backbutton from preventing logged users ? after login it redirects to the home page and from home page if i click browser back button it goes the previous page login.
is it good idea to disable backbutton from preventing logged users ?
I don't see the problem with users being able to go back to the login page. If you don't want them to log onto an other account while being already logged in, you could just redirect the users or throw an error page if you detect that the user is already logged in.

Django: redirect to same page after custom login

I have this code for a custom login:
def login(request):
if request.user.is_authenticated:
return render(request, 'listings/index.html', {})
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if not request.POST.get('remember_me', None):
request.session.set_expiry(0)
auth_login(request, user)
return redirect('dashboard')
else:
messages.error(request, "Les informations que vous venez d'entrer sont incorrects. Veuillez réessayer.")
return render(request, 'dashboard/login.html', {})
return render(request, 'dashboard/login.html', {'randomtip': random.choice(RandomTip.objects.all())})
And all my views have #login_required and #user_passes_test decorators. As you can see in the login function, when the user is authenticated and logged in, s/he gets redirected to dashboard.
But I have a session expiry limit (where users have their sessions expired after 6 minutes). And when they are in a specific page, they get redirected to the login after the expiry of the cookie. The problem here is that if they are in a page other than dashboard, after they login they get redirected to the dashboard.
I want them to stay in the same page after they login again. How can I know the path of the current page visited and put it here: return redirect(current_page)?
this is done automatically by django when the cookie expires the user won't pass the #login_required he will be passed to the login page with html attributes like this
http://127.0.0.1:8000/login/?next=/the_page_he_was_in/
the key here is /?next=/ in the url it will redirect the normal login redirect and send the user direct to the page he was in

Login required always render to home page

when I am using login_required it does not rendering to appropriate url it always render to home page only
login view
def login_view(request):
print(request.user.is_authenticated())
w="Welcome"
title = "Login"
form = UserLoginForm(request.POST or None)
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)
messages.success(request, "Successfully Logged In. Welcome Back!")
return HttpResponseRedirect("/")
return render(request, "registration/login.html", {"form":form, "title":title})
settings.py file
LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
I applied login required on contact us but when i am logging in then it is rendering to home page.
contact us view
#login_required
def contactformview(request):
form = ContactForms(request.POST or None)
if form.is_valid():
form.save()
return HttpResponse(' Thanks For Contacting WIth Us We Will Get Back To You Within 24 Hours')
return render(request, 'contact-us.html', {'form':form})
When Django redirects to the login page, it includes the next url in the querystring, e.g.
/login/?next=contact
Your login_view ignores the querystring and always returns HttpResponseRedirect("/"), so you will always be redirected to the homepage.
It would be better to use Django's login view instead of your own, because it handles the redirect for you. If you must use your own login view, you can look at the source code to see how Django handles the redirect, and adjust your view.

User authenticates on login page, but does not show as authenticated on redirected page

I've seen a lot of outdated posts mentioning render_to_response. From my understanding, redirect() should maintain the context.
Here's the code for my login view
def login(request):
context = {}
context['form'] = LoginForm
context['loginFailure'] = False
if request.POST:
username = request.POST['user']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_authenticated:
print('logged in on /login!')
return redirect('/')
else:
context['loginFailure'] = True
print('Invalid login on /login!')
return render(request,'q/login.html', context )
return render(request,'q/login.html', context )
It correctly prints to the terminal when I login with valid credentials.
On the index view, I have this code
if request.user.is_authenticated:
print("index: Authenticated!")
else:
print('index: Not authenticated...')
But every time I login successfully and /login/ prints a successful message, the index view tells me that I'm not authenticated. What do I need to do to maintain the context after a successful login?
You need to call django login also. doc ref
from django.contrib.auth import authenticate, login
if user is not None:
login(request, user)
print('logged in on /login!')
return redirect('/')

Requesting user-only page without context

I have a login webpage which authenticates the user correctly. When login page accepts user info and sends them to a default logged in page, django correctly gets user info and populates the page accordingly.
Also, when sent to login page from another django's webpage, or when logged in as a user, django will automatically redirect to a default page correctly.
However, after I just logged in as a standard user, entering login page by entering 127.0.0.1:8000/login/ in browser's addressbar or when linked to this page,
request.user.is_authenticated() will always return False.
Why is this happening? How come this isn't happening when logged in as superuser?
EDIT:
Here's the code in views.py:
if request.user.is_authenticated():
#redirect to logged in page
if request.method == "POST":
email = request.POST.get("email_input")
password = request.POST.get("password_input")
users = UserProfile.objects.all() # FIXME: Inefficient GET request
for user in users:
if user.user.email == email and check_password(password, user.user.password):
login(request, authenticate(username=email, password=password))
#go to logged in page
return render(request, "login/login.html", {"error_message": "Invalid email/password combination. Please retry",
"email": email})
return render(request, "login/login.html")
That's a funny implementation. I would suggest you use what's stated in the documentation instead:
from django.contrib.auth import authenticate, login
def my_view(request):
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)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.