Django 403 Forbidden CSRF - django

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' %}"

Related

Security Concerns with Login and Register Django HTML Template and Views.py

Do you have any security concerns with what I've done being implemented in a production web app? Either in the Django HTML Template or my views logic?
I would prefer to have the form in actual html rather than using {{ form }}. Is it ok to allow the user to implement very basic passwords?
views.py is:
from django.shortcuts import render, redirect
from django.contrib.auth import get_user_model
User = get_user_model()
from django.contrib.auth import authenticate, login as auth_login
from django.contrib import auth
from memberships.models import UserMembership
from django.contrib.auth.decorators import login_required
from companies.models import Profile
# Create your views here.
def register(request):
if request.method == "POST":
# User has info and wants an account now!
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.get(email=request.POST['email'])
return render(request, 'accounts/register.html', {'error': 'Email has already been taken'})
except User.DoesNotExist:
user = User.objects.create_user(request.POST['email'], password=request.POST['password1'])
auth.login(request, user)
company = Profile()
company.businessperson = request.user
company.first_name = request.POST['firstname']
company.last_name = request.POST['lastname']
company.company_name = request.POST['companyname']
company.phone_number = request.POST['phonenum']
company.save()
return redirect('memberships:payment')
else:
return render(request, 'accounts/register.html', {'error': 'Passwords must match'})
# User wants to enter info
return render(request, 'accounts/register.html')
def login(request):
if request.method == "POST":
user = authenticate(email=request.POST["email"], password=request.POST["password"])
if user is not None:
# Our backend authenticated the credentials
auth_login(request, user)
return redirect('dashboard')
else:
# Backend did not authenticate the credentials
return render(request, 'accounts/login.html', {"error": "Incorrect email and or password"})
else:
return render(request, 'accounts/login.html')
def logout(request):
if request.method == "POST":
auth.logout(request)
return redirect('login')
forms in login.html and register.html:
<!-- login.html -->
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="email" name="email" id="exampleInputEmail">
</div>
<div class="form-group">
<input type="password" name="password" id="exampleInputPassword" >
</div>
<input type="submit" value="Login">
</form>
<!-- register.html -->
<form action="{% url 'register' %}" method="POST" >
{% csrf_token %}
<input type="text" name="firstname" id="exampleFirstName" >
<input type="text" name="lastname" id="exampleLastName" >
<input type="text" name="companyname" id="exampleInputCompany" >
<input type="tel" name="phonenum" id="exampleInputPhone" placeholder="Phone Number">
<input type="email" name="email" id="exampleInputEmail" placeholder="Email" required>
<input type="password" name="password1" id="exampleInputPassword" placeholder="Password" required>
<input type="password" name="password2" id="exampleRepeatPassword" placeholder="Repeat Password" required>
<input type="submit" value="Register Account">
</form>

"next" is not redirecting to expected position

I am making a wallet app so if someone goes to http://127.0.0.1:8000/add_money/ to add money and they are not logged in they will be redirected to the login page with next there after the user logs in it should be redirected back to add_money but it is being redirected to their profile.
//ADD MONEY VIEW
def add_money(request):
if not request.user.is_authenticated():
return render(request, 'registration/login.html', {"next": '/add_money/'})
else:
if request.POST:
username = request.user.username
add_amount = request.POST['amount']
wallet = Wallet.objects.filter(username=username).update(add_money(add_amount))
now = datetime.now()
trans = Transaction(from_name=username, wallet_id=wallet.id, date=now, amount=add_amount)
trans.save()
return render(request, 'user_profile.html', {'user': request.user})
return render(request, 'registration/login.html', {"next": '/add_money/'})
//Login View
def user_login(request):
if 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)
if request.POST['next']:
return render(request, '/add_money/')
return render(request, 'user_profile.html',{'user': user, 'wallet': user.userprofile.wallet_id})
else:
return render(request, 'registration/login.html', {'error': 'User is not active'})
else:
return render(request, 'registration/login.html', {'error': 'User does not exist'})
else:
return render(request,'registration/login.html')
//login template
{% if next %}
<form action="/login/?next={{next}}" method="post">
<input type="hidden" name="next" value={{ next }}>
{%else%}
<form action="/login/" method="post" >
{% endif %}
USERNAME <input type="text" name="username">
PASSWORD <input type="password" name="password">
<input type="submit">
<input type="hidden" name="next">
{% csrf_token %}
</form>
//add_money template
<form action="user_profile.html" method="post">
Amount:<input type="number" name="amount">
<input type="submit" value="Submit">
<button type="button" name="cancel">Cancel</button>
</form>
I'm not sure it how it even manages to get to the account page since you're using the render tag as a mixture of render and redirect.
return render(request, '/add_money/')
You should return a redirect response back to the next url instead
return HttpResponseRedirect(request.GET['next'])
Also, you're passing the next to the login template, not the url
if not request.user.is_authenticated():
return render(request, 'registration/login.html', {"next": '/add_money/'})
you should redirect to the login page here as well with next as a get parameter
return HttpResponseRedirect('/login/?next={}'.format('/add_money/')
You should also look into using the provided url reversing methods instead of hard coding urls
You also should remove the whole if next in the template and just let the login action be the default for the page
{% if next %}
<form action="/login/?next={{next}}" method="post">
<input type="hidden" name="next" value={{ next }}>
{%else%}
<form action="/login/" method="post" >
{% endif %}
should be
<form method="post" >

Doesn't work custom login page in django 1.7

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))

Authentication in Django. How can we make password verification step or compare the user ID with those in the database?

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

Check existing password and reset password

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'})