Django's authenticate function seems to always be returning none, ive already checked out this thread and updated the authentication backends in the settigns.py file.
This is the code that i am using to save the accounts being created:
if request.method == 'POST':
# Getting the information from the filled in UserCreationForm
user_form = UserCreationForm(data=request.POST)
# If the the form is valid then save the users data to the database
# hash the password using set_password and save the user again
# set registered to True
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
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
# Not a HTTP POST, so these forms will be blank, ready for user input.
else:
user_form = UserCreationForm()
# Render the template depending on the context.
return render_to_response(
'contracts/register.html',
{'user_form': user_form, 'registered': registered}, context)
This seems to be working, since after i create a new user on the site, the access database its linked to updates with that username and the encrypted password.
The user_from is created from UserCreationForm which is:
class UserCreationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username','password','first_name','last_name','email','is_staff','is_active')
Here is the code in my user_login method which should be grabbing the username and password from the request and authenticating the combo
def user_login(request):
# context for the user's request.
context = RequestContext(request)
# form = AuthenticationForm()
# If the request is a HTTP POST
if request.method == 'POST':
# Gather the username and password provided by the user.
# This information is obtained from the login form.
user = request.user
userSubmit = user.username
passSubmit = user.password
#username = request.POST.get['username']
#password = request.POST.get['password']
user = authenticate(username = userSubmit, password=passSubmit)
#try:
# user = authenticate(username=userSubmit, password=passSubmit)
#except LockedOut:
# messages.error(request, 'You have been locked out because of too many login attempts. Please try again in 10 minutes.')
# If we have a User object, the details are correct.
# If None (Python's way of representing the absence of a value), no user
# with matching credentials was found.
else:
if user:
# Is the account active? It could have been disabled.
if user.is_active:
# If the account is valid and active, we can log the user in.
# We'll send the user back to the homepage.
login(request, user)
return redirect('home')
else:
# An inactive account was used - no logging in!
messages.error(request, 'Your account is disabled.')
else:
messages.error(request, 'The credentials you entered are invalid.')
# Bad login details were provided. So we can't log the user in.
# The request is not a HTTP POST, so display the login form.
# This scenario would most likely be a HTTP GET.
# No context variables to pass to the template system, hence the
# blank dictionary object...
return render_to_response('administrative/login.html', {'form': form}, context)
Related
I want to use django's default password reset view "PasswordResetView" which let's the user reset his password when he forgets it in a template that already has a view that i built on my own, after looking at the tutorials and the questions i found how to use it only on a different template that is made only for the password reset, but i don't want the user to go to a different page just to change his password when he forgets it, i want to make it in a bootstrap modal in the home page.
here is my home view that i want to add PasswordResetView functionality to it:
def home(request):
user = request.user
signin_form = SigninForm()
signup_form = SignupForm()
if request.method == "POST":
if 'signin_form' in request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
elif user is None:
messages.error(request, 'ُEmail or password is incorrect')
if 'signup_form' in request.POST:
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
context = {'signin_form': signin_form,'signup_form': signup_form}
return render(request, 'main/home.html', context)
PS: i tried copy pasting the source code of that view (PasswordResetView) from django's source code in my view but i found some errors because it's a class based view, so if you find this the proper way, guide me to do it
or if i can't merge them somehow how to create a custom one
this is what i found in the other answers which lets you use it in a certain template that has only that view (PasswordResetView) which is not what i want:
from django.contrib.auth import views as auth_views
path('password_reset/', auth_views.PasswordResetView.as_view(template_name="myapp/mytemplate.html",form_class=mypasswordresetform),name="reset_password"),
I'll give you a simple approach to having a password reset feature on your django application. Before having any code, let me give a brief exlanation of the process. What you want to do is get a user to input their email, check if there is any user with that email, then if there is one, send an email to that address with a uniquely generated link.
From this link, you should be able to extract the user object which you need to change password. An example would be to use django's signing module. This link will simply need to redirect the user to a template where there is a form with 2 fields i.e. New Password and Verify Password.
Django's generic views come with this functionality out-of-the-box if you are using Django's authentication module, but you aren't forced to use it, but its best to do so.
Here I'll only show you how to collect the email address on the same view as you said you wanted.
def home(request):
# ...your other code
if request.method == 'post':
if 'reset_password' in request.POST:
email = request.POST.get("email", "")
user_qs = User.objects.filter(email=email)
if not user_qs.exists():
# send error message to user here
else:
user = user_qs.get()
# send email with uniquely generated url here.
The other aspects of generating a URL and sending the mail, I believe you can research these separately. But I hope you now have an idea of where and what to search.
I have a question.
1. in Django I created a login page after login successfully. If I enter /accounts/login again I can see this url and I can login again.
How can disable login page after that user was login and if user enter url for login page get another page?
views.py
def user_login(request):
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:
login(request, user)
return redirect("home")
else :
messages.error(request, "Bad username or password")
return render(request, "login.html", context={})
tnx for help
You can "disable" it, by adding a check that verifies if the user is already authenticated, and then redirect it to somewhere else, like:
def user_login(request):
if request.user.is_authenticated:
return redirect('home')
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:
login(request,user)
return redirect("home")
else :
messages.error(request,"Bad username or password")
return render(request,"login.html",context={})
So the if statement checks if the user is authenticated (logged in), and if so, then we return a HTTP redirect response to a view (here 'home').
In Django versions before django-1.10, the check is request.user.is_authenticated() (so the method has to be called), but since django-1.10 this is a property.
But I would not call it a (security) problem. One could also see it as a feature, and for instance log in to another account.
I am getting a syntax error on the last else statement, i don't no where i am not doing it right but am assuming its a result of an idention error. sublime text auto idention not helped me out:
#csrf_exempt
def pagelogin(request):
context =RequestContext(request)
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
# Is the account active? It could have been disabled.
if user.is_active:
# If the account is valid and active, we can log the user in.
# We'll send the user back to the homepage.
login(request, user)
#return HttpResponseRedirect('/home/')
return render(request,'index.html')
else:
# An inactive account was used - no logging in!
return HttpResponse("Your account is disabled.")
else:
# Bad login details were provided. So we can't log the user in.
print "Invalid login details: {0}, {1}".format(username, password)
return HttpResponse("Invalid login details supplied.")
# The request is not a HTTP POST, so display the login form.
# This scenario would most likely be a HTTP GET.
else:
# No context variables to pass to the template system, hence the
# blank dictionary object...
#messages.success(request, 'You have successfully logged in to your account')
return render(request,'pagelogin.html')
Indent like this:
#csrf_exempt
def pagelogin(request):
context =RequestContext(request)
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
# Is the account active? It could have been disabled.
if user.is_active:
# If the account is valid and active, we can log the user in.
# We'll send the user back to the homepage.
login(request, user)
#return HttpResponseRedirect('/home/')
return render(request,'index.html')
else:
# An inactive account was used - no logging in!
return HttpResponse("Your account is disabled.")
else:
# Bad login details were provided. So we can't log the user in.
print "Invalid login details: {0}, {1}".format(username, password)
return HttpResponse("Invalid login details supplied.")
# The request is not a HTTP POST, so display the login form.
# This scenario would most likely be a HTTP GET.
else:
# No context variables to pass to the template system, hence the
# blank dictionary object...
#messages.success(request, 'You have successfully logged in to your account')
return render(request,'pagelogin.html')
I'm experimenting with Django and I tried to create a login/register application. Here's where I've stuck - I'm able to register users, but then I can't login with them. Here's the code I think is relevant:
views.py
def login(request, template='accounts/sign_in.html'):
if request.user.is_authenticated():
return redirect(reverse('games'))
if request.method == 'POST':
post = request.POST.copy()
if 'password' in post:
post['password'] = make_password(post['password'])
form = AuthenticationForm(data=post)
if form.is_valid():
login(request, form.get_user())
messages.success(
request, "Successfully logged in.", extra_tags='success')
return redirect(reverse('games'))
else:
messages.warning(
request, "Wrong username or password." + request.POST['username'] + " " + request.POST['password'], extra_tags='error')
return redirect(reverse('login'))
return views.login(request, template)
def register(request, template='accounts/sign_up.html'):
if request.user.is_authenticated():
return redirect(reverse('home'))
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
new_user = User(
username=form.cleaned_data['username'],
password=make_password(form.cleaned_data['password1']),
is_active=True,
)
new_user.save()
messages.success(request, "Your account was successfully created.")
return redirect(reverse('games'))
else:
form = RegisterForm()
return render(request, template, {'register_form': form})
When I try to log in with a user I've created (username: qwe, password: qweqweqwe), I get redjrected to login again, but the exact same username and password are printed in the message:
Wrong username or password.qwe qweqweqwe
However, when I try the interactive shell, here's what I get:
>>> User.objects.all()
[<User: admin>, <User: asd>, <User: qwe>]
>>> User.objects.all()[2]
<User: qwe>
>>> User.objects.all()[2].password
u'pbkdf2_sha256$10000$HM2k6uDntJ68$DLqHKcGxtJG7pJC7tbZcm29vB88LEgaw2xroqZEkTFw='
So I have such a user and it's a valid account.
I'm pretty sure you don't need to call make_password in this one:
if 'password' in post:
post['password'] = make_password(post['password'])
form = AuthenticationForm(data=post)
Just pass the normal request.POST to data and the form itself do the encryption and test it against the database. This is the fragment of AuthenticationForm's clean method where it do this:
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username and password:
self.user_cache = authenticate(username=username,
password=password)
...
You can see the whole definition here.
I suppose your using official make_password function from django.contrib,auth but take a look at the docs closely, normally, user register functions do this automatically so you won't have to do it.
Anyways:
Check the errors form is yielding after is_valid call and change your login code to this:
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
Hope this helps!
Issue no. 1 - wrong login()
This is probably the problem:
login(request, form.get_user())
You already have a login function and it happens to be a view. I suppose you want to confirm user authentication (form.is_valid() does not do that automatically).
More details are in the documentation of auth module:
How to log a user in
If you have an authenticated user you want to attach to the current
session - this is done with a login() function.
login()
To log a user in, from a view, use login(). It takes an HttpRequest
object and a User object. login() saves the user’s ID in the session,
using Django’s session framework.
Note that any data set during the anonymous session is retained in the
session after a user logs in.
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(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.
Issue no. 2 - wrong password
As Paulo mentioned, AuthenticationForm already handles password hashing. Please read the official documentation for examples:
Using the Django authentication system: Authentication in Web requests
Im new to Django and I know that to redirect after login I have to set the parameter 'page'. But this only works when the login is successful. How can i do the same thing when some error occurs??
Ps: Im currently also using django-registration with simple backend
I think it's what you are looking for:
# Login
def connection(request):
# Redirect to dashboard if the user is log
if request.user.is_authenticated():
return redirect('YourProject.views.home')
# Control if a POST request has been sent.
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None: #Verify form's content existence
if user.is_active: #Verify validity
login(request, user)
return redirect('/index') #It's ok, so go to index
else:
return redirect('/an_url/') #call the login view
return render(request, 'login.html', locals()) #You can remove local() it is for user's data viewing..