Requesting user-only page without context - django

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.

Related

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

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('/')

Django authentication stops working when I add a logout function

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.

invoke function just after user login in django

I was looking for a way to invoke a function (do_something) just after user logged-in.
def do_something(request):
# do blah-blah
return data
One way of doing is that I can check the referrer page using META['HTTP_REFERER'] if it comes through 'login' page or not.
But it doesn't make strong criteria if the page comes from any where else.
Is there any post_login_signal which can help me out for this issue.
There is the user_logged_in signal.
Create your own log in function. Something like the Django documentation example:
def login_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)
# Do what you want to do here
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.

Django, Redirecting staff from login to the admin site

So my site basically has 2 kinds of ways to login, one of them is for the common users, who get the regular screen that asks them for username and password, the other way its for staff.
The staff login should redirect them to the admin site after logging in, but for some reason the redirect doesnt happen, it stays on the same login page.
I use this condition on the login view.
if user is not None and user.is_active and user.is_staff:
auth.login(request,user)
return HttpResponseRedirect("/admin/")
The admin site its up and running in my url configuration and everything, but i dont know if this is the correct way to redirect to the admin site already on session.
Thanks, any help would be appreciated.
When a user logs in, login() will automatically redirect the user skipping the following line in your code:
return HttpResponseRedirect("/admin/")
Two possibilities:
If REDIRECT_FIELD_NAME (aka 'next') exists in your REQUEST fields, then the user is redirected to it right away.
If REDIRECT_FIELD_NAME is not found, then the user is redirected to LOGIN_REDIRECT_URL which you may have defined in your settings.py & if not, then it redirects to the default value for LOGIN_REDIRECT_URL.
So, it seems that your code doesn't set REDIRECT_FIELD_NAME, so naturally all users will end up being redirected to the path of LOGIN_REDIRECT_URL whatever that may be.
To solve this, set request.REQUEST['next'] = '/admin/' when you know the user is staff.
Then the redirect will happen automatically.
One way of logging in the the users and redirecting them according to their status could be:
from django.shortcuts import redirect
from django.contrib.auth import authenticate, login
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user.is_active:
# Redirecting to the required login according to user status.
if user.is_superuser or user.is_staff:
login(request, user)
return redirect('/admin/') # or your url name
else:
login(request, user)
return redirect('/')