I want to create my own login page uses the e-mail address and password in django 1.7.
When complete box and I click "login" page back to the login page.
My view:
def get_user_by_email(email):
try:
return User.objects.get(email=email)
except User.DoesNotExist:
return None
def login_by_email(request):
email = request.POST.get('email')
password = request.POST.get('password')
username = get_user_by_email(email)
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active():
login(request, email)
return HttpResponseRedirect(reverse("myapp:dashboard"))
return render_to_response('myapp/login.html', context_instance=RequestContext(request))
My url:
url(r'^login/$', views.login_by_email, name='login'),
My template login.html
{% block content %}
<form class="form-horizontal" name="LoginForm" action="{% url 'myapp:login' %}" method="post">
{% csrf_token %}
<div class="control-group">
<label class="control-label" for="email">Email</label>
<div class="controls">
<input type="text" id="email" value="{{email}}" placeholder="Email">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" name="password" id="password" placeholder="Password">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Login</button>
</div>
</div>
</form>
{% endblock %}
This line:
username = get_user_by_email(email)
Should be:
user_instance = get_user_by_email(email)
if user_instance:
username = user_instance.username
You are passing the user object to authenticate and it isn't able to log the user in.
Also, when you call the login function, you should pass the user as parameter:
login(request, user)
You are currently passing the email (django can't handle it this way)
Refer to the auth docs for more detail on how to handle custom login mechanisms
EDIT: Here's the complete view code
def get_user_by_email(email):
try:
return User.objects.get(email=email)
except User.DoesNotExist:
return None
def login_by_email(request):
email = request.POST.get('email')
password = request.POST.get('password')
user_instance = get_user_by_email(email)
if user_instance:
username = user_instance.username
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse("myapp:dashboard"))
return render_to_response('myapp/login.html', context_instance=RequestContext(request))
Related
recently I am seeing a weird error in my Django application. When I try to sign in, Chrome is stuck on "Processing request". After I click on the login button again it gives me the 403 Forbidden CSRF verification failed error. However, when I click on the Back button and press login again with the same user credentials it logs in successfully. I do not know why this is happening. I have two Django applications which 'home' and 'main', after correct credentials it should take the user to the view of 'home' applications.
My main/user_login.html
<form method="POST" action="{%url 'main:user_login' %}" class="form-signin">
{% csrf_token %}
<div class="form-label-group">
<input type="text" name="username" id="inputText" class="form-control" placeholder="Username" required autofocus>
<br/>
</div>
<div class="form-label-group">
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
</div>
<div class="custom-control custom-checkbox mb-3">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Remember password</label>
</div>
<input type="submit" class="form-control" name="" value="Login">
<hr class="my-4">
<p>Don't have account? Sign up here</p>
{% if message %}<p style="color: red;">{{ message }}</p>{% endif %}
Forgot Password
</form>
my main/views.py:
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request,user)
messages.info(request, "Successfully signed in")
return redirect(reverse('home:home'))
else:
message = 'Sorry, the username or password you entered is not valid please try again.'
return render(request, 'home/user_login.html', {'message':message})
else:
message = 'Sorry, the username or password you entered is not valid please try again.'
return render(request, 'home/user_login.html', {'message':message})
else:
form=AuthenticationForm()
return render(request, 'home/user_login.html', {"form":form})
my home/views.py:
#login_required
def home(request):
context = {
'posts': Post.objects.all()
}
return render(request, 'home/home.html', context)
I do not understand what is causing the issue which as I mentioned before after going back and clicking on login again the user can successfully login.
Thanks in advance!
Edit: I have realized what causes the error it is the else statement that throws the error message. I have changed my view right now it does not give me an error but I have to click on the login button twice else it would get stuck again. My view is now:
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:
return redirect('home:home')
else:
messages.error(request,'Sorry, the username or password you entered is not valid please try again.')
return HttpResponseRedirect('/')
else:
form=AuthenticationForm()
return render(request, 'main/user_login.html', {"form":form})
And my user_login.html is now:
<form method="POST" action="{% url 'main:user_login' %}" class="form-signin">
{% csrf_token %}
<div class="form-label-group">
<input type="text" name="username" id="inputText" class="form-control" placeholder="Username" required autofocus>
<br/>
</div>
<div class="form-label-group">
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
</div>
<div class="custom-control custom-checkbox mb-3">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Remember password</label>
</div>
<input type="submit" class="form-control" name="" value="Login">
<hr class="my-4">
<p>Don't have account? Sign up here</p>
{% for message in messages %}
<p style="color: red;">{{ message }}</p>
{% endfor %}
Forgot Password
</form>
This is causing the issue:
else:
messages.error(request,'Sorry, the username or password you entered is not valid please try again.')
return HttpResponseRedirect('/')
Try this one:
#login_required
def home(request):
post = Post.objects.all()
context = {'post':post}
return render(request, 'home/home.html', context)
I think the problem might be in else block.
Just try this one:
def user_login(request):
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request,user)
messages.info(request, "Successfully signed in")
return redirect(reverse('home:home'))
else:
message = 'Sorry, the username or password you entered is not valid please try again.'
return render(request, 'home/user_login.html', {'message':message})
else:
form=AuthenticationForm()
return render(request, 'home/user_login.html', {"form":form})
Django's built-in tags need spaces
fix this in your form: action="{% url 'main:user_login' %}"
I am not using django default admin dashboard and i am using my own custom template for the admin.but here i got some problem while editing and updating the user.I want to make email of every user unique in the database this code in my forms.py does pretty well while adding the user but while updating it i got some problem regarding the email.Since I have done the email unique in forms.py it is giving me error while updating also.How can i update users so that the edited user can have the same email but not same as the other user's email address.
forms.py
class RegisterForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
class Meta:
model = User
fields = ['username', "email", "password1", "password2",'is_superuser','is_staff','is_active']
views.py
def register(request):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to register users.')
return redirect('students:home')
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.save()
messages.success(request,'user created with username {}'.format(user.username))
return redirect('students:our_users')
else:
form =RegisterForm()
return render(request,'students/register.html',{'form':form})
def editusers(request,id):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to perform this action.')
return redirect('students:our_users')
user = User.objects.get(id=id)
return render(request,'students/edit_users.html',{'user':user})
def updateusers(request,id):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to perform this action.')
return redirect('students:our_users')
user = User.objects.get(id=id)
form = RegisterForm(request.POST,instance=user)
if form.is_valid():
user = form.save(commit=True)
user.save()
messages.success(request,'{} updated'.format(user.username))
return redirect('students:our_users')
else:
messages.error(request,'Error in Form')
return redirect('students:edit_user',user.id)
register template
<form action="" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Add</button>
</div>
</form>
edituser template
<form action="{% url 'students:update_user' user.id %}" method="post">
{% csrf_token %}
<div class="form-group"><label for="id_username">Username</label><input type="text" name="username" maxlength="150" autofocus class="form-control" value="{{user.username}}" placeholder="Username" title="Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only." required id="id_username">
<small class="form-text text-muted">Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.</small>
</div>
<div class="form-group"><label for="id_email">Email</label><input type="email" name="email" value="{{user.email}}" class="form-control" placeholder="Email" title="" required id="id_email"></div>
<div class="form-group"><label for="id_password1">Password</label><input type="password" name="password1" value="{{user.password}}" class="form-control" placeholder="Password" title="Your password must contain at least 8 characters.Your password can't be entirely numeric." required id="id_password1">
<small class="form-text text-muted"><ul><li>Your password must contain at least 8 characters.</li><li>Your password can't be entirely numeric.</li></ul></small>
</div>
<div class="form-group"><label for="id_password2">Password confirmation</label><input type="password" name="password2" value="{{user.password}}" class="form-control" placeholder="Password confirmation" title="Enter the same password as before, for verification." required id="id_password2">
<small class="form-text text-muted">Enter the same password as before, for verification.</small>
</div>
<div class="form-group"><div class="form-check"><input type="checkbox" name="is_superuser" {% if user.is_superuser %}checked="checked" {% endif %}
class="form-check-input" id="id_is_superuser"><label class="form-check-label" for="id_is_superuser" title="Designates that this user has all permissions without explicitly assigning them.">Admin status</label>
<small class="form-text text-muted">Designates that this user has all permissions without explicitly assigning them.</small>
</div></div>
<div class="form-group"><div class="form-check"><input type="checkbox" name="is_staff" {% if user.is_staff %}checked="checked" {% endif %} class="form-check-input" id="id_is_staff"><label class="form-check-label" for="id_is_staff" title="Designates whether the user can log into this admin site.">Staff status</label>
<small class="form-text text-muted">Designates whether the user can log into this admin site.</small>
</div></div>
<div class="form-group"><div class="form-check"><input type="checkbox" {% if user.is_active %}checked="checked" {% endif %} name="is_active" class="form-check-input" id="id_is_active"><label class="form-check-label" for="id_is_active" title="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.">Active</label>
<small class="form-text text-muted">Designates whether this user should be treated as active. Unselect this instead of deleting accounts.</small>
</div></div>
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Update</button>
</div>
</form>
You can do it like this:
def clean_email(self):
email = self.cleaned_data['email']
if self.instance and self.instance.pk:
return email
else User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
Here I am checking if form has any instance and if that instance has any primary key. This instance attribute is set in form when you pass it from view, for example in your code: form = RegisterForm(request.POST,instance=user).
I have created two different types of users - truck & company. Here is my registration page for a user
After registering, the data about whether the user is a truck or company will go to the database.
In my login page,
only Email and Password are to be entered. In my custom user creation form, I added the field username = email.
When I am trying to login with valid credentials, the page is not redirecting me to a particular page according to the user-type. Instead, an error which I created for invalid credentials in login.html is raising - "Your email and password didn't match. Please try again."
here's my code:
views.py:
def login_view(request):
title = "Login"
if request.method == 'POST':
form = LoginForm(data=request.POST)
email = request.POST.get('email', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=email, password=password)
if form.is_valid():
auth.login(request, user)
user_type = form.cleaned_data['Label']
if user.is_active & user_type == 'Truck':
return HttpResponseRedirect('/post_load/')
elif user_type == 'Company':
return HttpResponseRedirect('/live_deal/')
else:
form = LoginForm()
return render(request, 'registration/login.html', {'form' : form, 'title': title})
urls.py:
# url(r'^login/$', views.login_view),
# url(r'^accounts/login/$', views.login_view),
url(r'^login/$', 'django.contrib.auth.views.login', {'authentication_form': LoginForm}),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'authentication_form': LoginForm}),
forms.py:
class LoginForm(auth.forms.AuthenticationForm):
email = forms.EmailField(label=_("Email"),widget=forms.EmailInput)
CHOICES= (('Truck', 'Truck'),('Company', 'Company'),)
Label = forms.ChoiceField(choices=CHOICES, label='Label', widget=forms.RadioSelect())
login.html:
{%extends "registration/header.html"%}
{% block content %}
{% if form.errors %}
<p>Your email and password didn't match. Please try again.</p>
{% endif %}
<form class="form-horizontal" method="post" action = "." >{%csrf_token%}
<div class="panel panel-default login">
<div class="panel-heading">
<span class="glyphicon glyphicon-lock"></span> Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<div class='col-sm-6 col-sm-offset-4'>
<table border="0">
<div class="col-sm-4">
<tr><th><label for="id_user" class="col-sm-4 control-label">Email:</label></th><td>{{ form.email }}</td></tr> </div>
<div class="col-sm-4">
<tr><th><label for="id_password" class="col-sm-4 control-label">Password:</label></th><td>{{ form.password }}</td></tr> </div>
</table> </div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<div class="checkbox">
<label>
<input type="checkbox"/>
Remember me
</label>
</div>
</div>
</div>
<div class="form-group last">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-success btn-sm">
Sign in</button>
<input type="hidden" name="next" value="/" />
<label class="col-sm-offset-3">
Forget Password?
</label>
</div>
</div>
</form>
</div>
<div class="panel-footer">
Not Registered? Register</div>
</div>
</form>
{% endblock %}
{% if form.errors %}
<p>Your email and password didn't match. Please try again.</p>
This error is rather broad. You could loop through it to see the actual errors.
Better yet; don't use your own authentication system just use Django's built-in system which also allows you to add extra fields to the user model.
Example:
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.
...
Note, you don't need to write your own login view, you can also use Django's login system to handle the form, pass reset/change, urls and templates (which you can override with your own template):
urls:
urlpatterns = [
url('^', include('django.contrib.auth.urls')),
]
Then /login/ will be your login page.
After it works with the Django contrib auth module, extend it with your own custom HTML login form.
django.contrib.auth.views
I'm trying to build a basic django web application. I am using the authentication and auth model now and my code requires username and password only. How can we make it better by adding password verification step or user id check service?
def authenticate(request):
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
if user == None:
return HttpResponse('username or password error')
auth.login(request, user)
#I requested "request"!!!!
return HttpResponseRedirect(request.POST.get('next', '/') or '/')
def signup(request):
return render_to_response('signup_account.html', locals(), RequestContext(request))
def create(request):
#user = User.objects.create_user(username=request.POST['username'], first_name=request.POST['userfirstname'], last_name=request.POST['userlastname'],
# email=request.POST['email'],
# password=request.POST['password'])
user = User.objects.create_user(username=request.POST['username'],
password=request.POST['password'])
print 'create', user
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
print 'authenticated', user
auth.login(request, user)
#Here what I want to do is to allow users to screen their wrong id.
#+ Password check.
subject = 'Thank you'
message = 'Welcome home /n I am so happy'
from_email = settings.EMAIL_HOST_USER
to_list = [user.email,settings.EMAIL_HOST_USER ]
send_mail(subject, 'Wow, this email sending altorithm is working.\n What a marvelous function is.', settings.EMAIL_HOST_USER,
to_list, fail_silently=False)
return HttpResponseRedirect(request.POST.get('next', '/') or '/')
The below is the login html code.
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.css">
</head>
<body>
<h1>Sign Up</h1>
<div class="container">
<form class="form" action="/accounts/create" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}">
<input type="hidden" name="next" value="{{ request.GET.next }}">
<div class="form-group">
<label>User ID</label>
<input class="form-control" type="text" name="username">
</div>
<div class="form-group">
<label>First Name</label>
<input class="form-control" type="text" name="userfirstname">
</div>
<div class="form-group">
<label>Last Name</label>
<input class="form-control" type="text" name="userlastname">
</div>
<div class="form-group">
<label>Email</label>
<input class="form-control" type="email" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input class="form-control" type="password" name="password">
</div>
<input type="submit" class="btn btn-primary" value="Sign Up">
</form>
</div>
</body>
</html>
I'm a really beginner and I am even forced to think that this would be possible by inserting code into html file directly. I'm looking forward to hearing any feedback! Thank you.
You have username and password there ... So pass that into try ...
username = request.POST['username']
password = request.POST['password']
try:
user = User.objects.get(username=username)
if user.check_password(password):
username = user.username
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, "Welcome")
return HttpResponseRedirect(#your url
else:
messages.error(request, "Password not match")
return HttpResponseRedirect(#your url
except User.DoesNotExist:
pass
views.py to save the password:
elif 'reset_password' in request.POST:
if request.POST['reset_password'].strip():
saveuser = User.objects.get(id=user.id)
saveuser.set_password(request.POST['reset_password']);
saveuser.save()
userform = UserForm(instance=saveuser)
return redirect('incident.views.about_me')
popup box to get the old password and new password
<div id="overlay_form" style="display:none">
<form method="post" action=".">
{% csrf_token %}
<h2>Reset Password</h2><br />
<table>
<tr><td>Enter your old password</td><td>
<input type="text" name="old_password" id="old_password" maxlength="30" /></td></tr>
<tr><td>Enter your new password</td><td><input type="text" name="new_password" id="new_password" maxlength="30" /></td></tr>
<tr><td>Confirm your new password</td><td><input type="text" name="reset_password" id="reset_password" maxlength="30" /></td></tr>
</table>
<div style="width:180px;float:right;margin:20px 5px 0 10px">
{% include "buttons/save.html" %}
<button style="margin-right:10px;" type="button" id="close" name="cancel" class="forward backicon">
<img src="{{ STATIC_URL }}images/button-icon-ir-back.png" width="12" height="17" alt="" />
Cancel</button>
</div>
</form>
</div>
I am able to save the new password,but i want to know the following things
How to check the entered old password is correct with existing password.
How to validate new password field and confirm password field.Which validation is better to perform.
Need some help.
This is how you would check for old password - before the set_password,
user.check_password(request.POST['reset_password'])
Also, check for password confirmation in the following way.
elif 'reset_password' in request.POST:
old_password = request.POST['old_password'].strip()
reset_password = request.POST['reset_password'].strip()
new_password = request.POST['new_password'].strip()
if old_password && reset_password && reset_password == new_password:
saveuser = User.objects.get(id=user.id)
if user.check_password(old_password):
saveuser.set_password(request.POST['reset_password']);
saveuser.save()
userform = UserForm(instance=saveuser)
return redirect('incident.views.about_me')
It is a much better approach to use a form.
Django Code to check if the password entered by user matches the actual old password; if it does not, raise validation error in django form. Also, update the password if both of the passwords match.
Tested on (Django 1.10, Python 3.4)
forms.py
from django import forms
class changePassForm(forms.Form):
old_password_flag = True #Used to raise the validation error when it is set to False
old_password = forms.CharField(label="Old Password", min_length=6, widget=forms.PasswordInput())
new_password = forms.CharField(label="New Password", min_length=6, widget=forms.PasswordInput())
re_new_password = forms.CharField(label="Re-type New Password", min_length=6, widget=forms.PasswordInput())
def set_old_password_flag(self):
#This method is called if the old password entered by user does not match the password in the database, which sets the flag to False
self.old_password_flag = False
return 0
def clean_old_password(self, *args, **kwargs):
old_password = self.cleaned_data.get('old_password')
if not old_password:
raise forms.ValidationError("You must enter your old password.")
if self.old_password_flag == False:
#It raise the validation error that password entered by user does not match the actucal old password.
raise forms.ValidationError("The old password that you have entered is wrong.")
return old_password
views.py
def settings(request):
if request.user.is_authenticated:
form = changePassForm(request.POST or None)
old_password = request.POST.get("old_password")
new_password = request.POST.get("new_password")
re_new_password = request.POST.get("re_new__password")
if request.POST.get("old_password"):
user = User.objects.get(username= request.user.username)
#User entered old password is checked against the password in the database below.
if user.check_password('{}'.format(old_password)) == False:
form.set_old_password_flag()
if form.is_valid():
user.set_password('{}'.format(new_password))
user.save()
update_session_auth_hash(request, user)
return redirect('settings')
else:
return render(request, 'settings.html', {"form": form})
else:
return redirect('login')
settings.html
<h1>Settings Page</h1>
<h2>Change Password</h2>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="Submit" value="Update"></input>
</form>
<form class="form-horizontal" action="/your_views/reset_password/" method="post">
{% csrf_token %}
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="Old password" id="old_password" name="old_password" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="New password" id="password1" name="password1" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="Re-new password" id="password2" name="password2" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-block btn-success" style="background: #00A79D;">Reset</button>
</div>
</div>
</form>
I implemented a method for Sign In with JWT and what it does is:
Fetches the email and password that is send with the request and
converts it into a string variable
I check if the email already
exists in the custom user model i made.
If the user already
exists, i convert the object model to dictionary so that i can get
its particular password.
In that i match the password
corresponding to user model and the password that is send with the
post request.
if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.
In all other cases the email and password don't match and i return "No Match"
Suppose the request is {"email":"xyz#gmail.com", "password":"12345" }
#api_view(['POST'])
def signin(request):
email = list(request.data.values())[0] #gets email value from post request {"email":"xyz#gmail.com", "password":"123"} -> this xyz#gmail.com
password = list(request.data.values())[1] #gets password value from post request {"email":"xyz#gmail.com", "password":"123"} -> this 123
usr = User.objects.filter(email=email).exists() #checks if email exists
if usr:
dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
branch = dictionary["branch"]
id = dictionary["id"]
encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
else:
return Response({'No Match'})
return Response({'No Match'})