"user = authenticate(request, username=username, password=password)" user is none - django

def login_page(request):
form = LoginForm(request.POST or None)
context = {
"form": form
}
print("User logged in")
#print(request.user.is_authenticated())
if form.is_valid():
print(form.cleaned_data)
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(request, username=username, password=password)
print(user)
print(request.user.is_authenticated())
if user is not None:
print(request.user.is_authenticated())
login(request, user)
# Redirect to a success page.
context['form'] = LoginForm()
return redirect("/")
else:
# Return an 'invalid login' error message.
print("Error")
return render(request, "auth/login.html", context)
Hello, I have started playing around in Django, but in a tutorial, when a tutor clicks submit, it authenticates the user ... I found almost the same problem on stack overflow already, but problem is, that a guy had a string instead of variables ( username = 'username' ) but problem is that when I click submit I get an error :
User logged in
{'username': 'test123', 'password': 'test'}
None
False
Error
User logged in is just a string in print()
None <- print(user)
False <- print(request.user.is_authenticated())
Error <- else: print("Error")
I am struggling for an hours with this problem ( we have the same version of Django ) Django==1.11.4

So I am not totally sure what exactly is causing your problems here.
I know this probably isn't what they do in the tutorial, but my suggestion to you would be to use the built in Django authentication views. That way you don't have to repeat code that is already done for you.
The views are very simple to use. All you need to do is set the proper route in your URL and then create a template under the directory 'registration/login.html'.
First set proper settings in your settings.py file(I'm including the login and logout steps because they go hand-in-hand):
LOGIN_REDIRECT_URL = '/page/you/redirect/to/'
LOGOUT_REDIRECT_URL = '/your/login/page/'
Then set URLs:
urls.py
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from django.conf import settings
urlpatterns = [
url(r'^login/$', auth_views.login, {'redirect_authenticated_user': True},name='login'),
url(r'^logout/$', auth_views.logout, {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'),
]
Then finally in your templates folder that is within the same app as the urls.py file where you put the login and logout routes, create a folder named "registration" and create an html file called "login.html".
Finally, your "login.html" file can simply be this:
{% block title %}Login{% endblock %}
{% block content %}
<body>
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
</body>
{% endblock %}
When you want to logout, just put a button wherever you want and link it to "/logout". And after that, authentication is done!

Related

Forbidden (403) CSRF verification failed Request aborted

I am getting a 403 error while I tried most of the responses in the forum to the same problem, but no luck! This registration code is originally from tango with django site, but it is not working on django 1.10.
Any help would be appreciated, here are the files I use:
views.py:
def register(request):
# Like before, get the request's context.
context = RequestContext(request)
# A boolean value for telling the template whether the registration was successful.
# Set to False initially. Code changes value to True when registration succeeds.
registered = False
# If it's a HTTP POST, we're interested in processing form data.
if request.method == 'POST':
# Attempt to grab information from the raw form information.
# Note that we make use of both UserForm and UserProfileForm.
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
# If the two forms are valid...
if user_form.is_valid() and profile_form.is_valid():
# Save the user's form data to the database.
user = user_form.save()
# Now we hash the password with the set_password method.
# Once hashed, we can update the user object.
user.set_password(user.password)
user.save()
# Now sort out the UserProfile instance.
# Since we need to set the user attribute ourselves, we set commit=False.
# This delays saving the model until we're ready to avoid integrity problems.
profile = profile_form.save(commit=False)
profile.user = user
# Did the user provide a profile picture?
# If so, we need to get it from the input form and put it in the UserProfile model.
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
# Now we save the UserProfile model instance.
profile.save()
# Update our variable to tell the template registration was successful.
registered = True
# Invalid form or forms - mistakes or something else?
# Print problems to the terminal.
# They'll also be shown to the user.
else:
print (user_form.errors, profile_form.errors)
# Not a HTTP POST, so we render our form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
user_form = UserForm()
profile_form = UserProfileForm()
# Render the template depending on the context.
return render_to_response(
'heaven/register.html',
{'user_form': user_form, 'profile_form': profile_form, 'registered': registered},
context)
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home,name='home'),
url(r'^home/', views.home, name='home'),
url(r'^register/', views.register, name='register'), # ADD NEW PATTERN!
]
html template:
<!DOCTYPE html>
<html>
<head>
<title>Heavenly</title>
<style>
*{font-family:Arial}
h1 {color:red;}
</style>
</head>
<body>
<h1>Register with Heavenly</h1>
{% if registered %}
<strong>thank you for registering!</strong>
Return to the homepage.<br />
{% else %}
<strong>register here!</strong><br />
<form id="user_form" method="post" action="/register/"
enctype="multipart/form-data">
{% csrf_token %}
<!-- Display each form. The as_p method wraps each element in a paragraph
(<p>) element. This ensures each element appears on a new line,
making everything look neater. -->
{{ user_form.as_p }}
{{ profile_form.as_p }}
<!-- Provide a button to click to submit the form. -->
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
</body>
</html>
https://docs.djangoproject.com/en/1.10/releases/1.10/#features-removed-in-1-10
The dictionary and context_instance parameters for the following functions are removed:
django.shortcuts.render()
django.shortcuts.render_to_response()
django.template.loader.render_to_string()
Use render instead.
https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#render

Django Custom Backend : Cannot Login when using custom backend for authentication with email

My primary requirement is to have Email authentication. Though my custom authentication backend seems to work fine, user.is_anoynymous() function is still True even after succesfully authenticating with my custom backend. When using the default authentication model everything seems fine.
views.py:
from testapp.models import *
from django.http import HttpResponseRedirect,HttpResponse,Http404,QueryDict
from django.shortcuts import render_to_response, RequestContext
from django.template import Context
from django.core.paginator import Paginator,QuerySetPaginator
from django.template.loader import get_template
from django.contrib.auth import logout,authenticate,login
from django.contrib.auth.views import *
from testapp.forms import *
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView
from testapp.backends import EmailBackend
from testapp.backends import EmailBackend
def main_page(request):
return render_to_response('main_page.html',{
'user':request.user
})
def loggedout(request):
logout(request)
return HttpResponseRedirect('/')
def custom_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password1']
cb = EmailBackend()
user = cb.authenticate(email,password)
# return HttpResponse(user.username)
if user is not None:
if user.is_active:
login(request,user)
return HttpResponseRedirect('/')
else:
return HttpResponse('USer is not Active')
else:
return HttpResponse('USer Not found')
else:
form = LoginForm()
page_var = RequestContext(request, {
'form':form,
})
return render_to_response('customlogin.html',page_var)`
backends.py:
from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend
class EmailBackend(ModelBackend):
def authenticate(self,email= None,password= None):
try:
user = User.objects.get(email=email)
if user is not None:
if user.check_password(password):
return user
else :
return None
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`
settings.py:
AUTHENTICATION_BACKENDS = ('testapp.backends.EmailBackend','django.contrib.auth.backends.ModelBackend')
main_page.html:
{% extends "base.html" %}
{% block title %}Welcome to Django Bookmarks{% endblock %}
{% block head %}Welcome to Django Bookmarks{% endblock %}
{% block content %}
{% block customadd %}
kskdsdsdl;sd
{% endblock %}
{% if user.username %}
<p>Welcome {{ user.username }}!
Here you can store and share bookmarks!</p>
{% else %}
<p>Welcome anonymous user!
You need to login.</p>
{% endif %}
{% endblock %}
Now although the main_page.html is called after successfully authentication, In main page {{user.username}} is always None and hence main_page.html opens as anonymous user.
user.is_anonymous() in main_page function in view.py returns True. What mistake am I making? After redirect to main_page.html I should see the user as logged in.
Edit 1: Last time I purposefully didn't put all the packages I included in views.py so I updated it now.
Django provides a login view. I recommend that you use this rather than writing your own.
If you use the Django login view, Django will use your authentication backend, because you have added it to the AUTHENTICATION_BACKENDS setting.
You would need to make a small change to the backend - change the field name from email to username so that it matches the login form. You would still filter the user based on their email.
def authenticate(self, username=None, password= None):
try:
user = User.objects.get(email=username)
If you continue to use your own login view, I can see a couple of possible issues. Firstly, you should import the authenticate method, and call that instead of instantiating your login backend.
from django.contrib.auth import authenticate
def custom_login(request):
...
user = authenticate(email=email, password=password)
...
Secondly, when you call login(request, user), make sure you have imported the correct login method, and not the login view I mentioned above.
from django.contrib.auth import login
Sorry, I don't see anything obviously wrong in your code. I'd recommend using Python's logging to aid in troubleshooting this.
Based on my own painful experience using email for authentication, you'll want to match case-insensitively because a lot of people will enter TheirEmail#likeThis.com. :)
user = User.objects.get(email__iexact=email)
...or only store lowercase email addresses. One project I worked on ended up with duplicate entries due to this.
Also, if that query succeeds, user will never be None, so you can skip that test and simplify your try-except block:
try:
user = User.objects.get(email__iexact=email)
if user.check_password(password):
return user
else:
logger.debug('password check failed')
except User.DoesNotExist:
logger.debug('user does not exist')
return None

Building a login module in Django

I'm trying to build a login module in django that works independently from the page you are on.
I'm defining the login module in a base.html template that contains the header (the login module sits in the header) all other pages extend this base template.
My plan was to pass the error through the context dictionary, the problem is that I don't know how to make the function render() render the template from which the user attempted to login.
this is my view code:
def login(request):
context_dict = {}
if request.POST:
username = request.POST.get('login_username')
password = request.POST.get('login_password')
user = authenticate(username=username, password=password)
if not user:
context_dict['error'] = 'שם משתמש או סיסמא אין נכונים'
elif not user.is_active:
context_dict['error'] = 'חשבונך נחסם, אם הינך חושב שזאת טעות צור קשר עם מנהל בהקדם.'
else:
login(request,user)
redirect(request.META.get('HTTP_REFERER'))
render(request, ', context_dict)
Finally figured it out, the trick is using the Django messages framework.
here is the code and explanation for anyone who wants to implement something similar:
simple url routing in urls.py file
url(r'^login/$', views.login, name='login'),
url(r'^logout/$', views.logout, name='logout'),
two views, one for login one for logout
def login(request):
if request.POST:
username = request.POST.get('login_username')
password = request.POST.get('login_password')
user = authenticate(username=username, password=password)
if not user:
messages.add_message(request, messages.INFO, 'wrong username or password')
elif not user.is_active:
messages.add_message(request, messages.INFO, 'your account is disabled')
else:
django_login(request,user)
return redirect(request.META.get('HTTP_REFERER'))
return redirect(request.META.get('HTTP_REFERER'))
def logout(request):
django_logout(request)
return redirect(request.META.get('HTTP_REFERER'))
modified import to avoid a recursion error (in views.py)
from django.contrib.auth import authenticate, login as django_login, logout as django_logout
and finally displaying message in template
{% if messages %}
{% for message in messages %}
<div class='login_error'>
{{ message }}
</div>
{% endfor %}
{% endif %}

Django not authenticated redirect

What would be the best implementation to redirect a user who is not signed in? Is there a better way then to use a #is_autenticated type decerator in every single view?
The alternative I have thought of is to have a base.html which checks for is_authenticated and every html will extend base. Ex:
base.html
{% if request.user.is_authenticated %}
{% block content %}
content here
{% endblock content %}
{% else %}
redirect
I feel though this way puts view logic into the template which really doesn't sit well but it would avoid a decorator on every function.
You could use some middleware. Personally, I think having the redirect in the template (I'm assuming in javascript code) is very ugly. Django-stronghold (https://github.com/mgrouchy/django-stronghold) is nice if most views require authentication.
Django has an in-built authentication model.Authentication logic should always be in the views and including view logic in the template is a bad practice.Once the user is authenticated, you can render a homepage from the views along with a welcome message.You can do the following:
from django.contrib.auth import authenticate
# login to home page -
def home(request):
try:
username = password = ''
if request.POST:
username = request.POST['username']
password = request.POST['password']
print username
print password
user = authenticate(username=username, password=password)
print "User value is",user
if user is not None:
if user.is_active:
login(request, user)
request.session['username'] = username
return render_to_response('home.html',{"message": "Welcome"})
# Redirect to a success page.
else:
return render_to_response('login.html',{"message": "User is Inactive"})
# Return a 'disabled account' error message
else:
return render_to_response('login.html',{"message": "Invalid Credential"})
else:
return render_to_response('home.html',{"user" : request.session['username']})
except:
return render_to_response('error.html',{"message": sys.exc_info()[0]})

django - multiple login redirects

I want to allow the users to go to their user page by default (like: mywebsite.com/userpage) when they use the login form.
Also if they go to some other password protected page on the web site redirect them to the login page first and once authenticated get them back to the original page they were trying to access.
This is what I have so far for the login function:
views.py
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
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 successpage
if request.POST['next']:
return HttpResponseRedirect(request.POST['next'])
else:
return HttpResponseRedirect("/" + username + "/")
else:
errors = 'This account has been disabeled.'
else:
# Return an 'invalid login' error message.
errors = 'There is a problem with the user name and/or the password. Please try again.'
else:
form = AuthenticationForm()
return render_to_response("registration/my_login.html", locals(), context_instance=RequestContext(request))
urls.py
urlpatterns = patterns('',
url(r'^login/$', user_login,),
my_login.html
<form action="." method="post" >{% csrf_token %}
{{errors}}
{{ form.as_p }}
<p class="submit"><button type="submit" name="login_user_button" value="Login">Log in</button></p>
<input type="hidden" name="next" value="{{ next }}">
</form>
My problem is that I don't know how to get the values of the "next" variable so I can use it in my user_login function for the redirect.
As you can see I tried to get it with request.POST['next'] but comes with an empty string so for some reason no value gets signed to the "next" variable.
Any ideas?
My recommendation - don't bother screwing around with the login function. You're just reinventing the wheel. Instead, use the login view that comes with the django.auth module, and have that send users to an interstitial page (with a URL defined in settings.LOGIN_REDIRECT_URL) that redirects them where they need to go.
This interstitial view could be something as simple as the following:
#login_required
def index(request):
return redirect('user-page', request.user.username)
Note that I've changed that redirect to use a named view. You don't want weird stuff to happen if a user gives himself a username that coincides with a site url!
Also note the login_required decorator. This automatically gives you the login page redirect you require.