Django : CSRF token missing or incorrect [duplicate] - python

This question already has answers here:
Django: CSRF token missing or incorrect
(4 answers)
Closed 9 years ago.
Django noob here ! I've tried basically every solution online and I still have the error (one Chrome) "CSRF token missing or incorrect" while Opera and Firefox return "CSRF cookie not set" instead...? Here are my files :
views.py
# views.py
from django.shortcuts import render_to_response
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.template import RequestContext
from django.core.context_processors import csrf
def dashboard(request):
state = "log in"
if request.user.is_authenticated():
return render_to_response('memberbrd.html')
elif request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/')
else:
error = "inactive"
else:
error = "wrong username or password"
render_to_response('visitorbrd.html', {'errors': error}, context_instance = RequestContext(request)) # I've also tried without context_instance, without passing errors...
else:
return render_to_response('visitorbrd.html')
urls.py
#urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
from mission.views import *
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', dashboard),
)
visitorbrd.html
{% extends "base.html" %}
{% block content %}
{% if state %}
<p>{{ state }}</p>
{% endif %}
<form action="." method="POST">{% csrf_token %}
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next|escape }}" />
</form>
{% endblock %}
Thanks !

You're not using RequestContext for the final render_to_response which is responsible for actually showing the form.

The previous answer is absolutely correct. A RequestContext is not required to output the form itself, though. This is handled by the Form class. The problem is that a new CSRF Token needs to be generated via the request and this is done through Django's middleware. The middleware only has access to the context variables and so by that logic, it needs the RequestContext to do this.
On a side note, I prefer Django's "render" function over "render_to_response." There are some times in which this function is too generic, but for a newer user, the savings on typing are nice and the code looks a lot cleaner. I copied the example from Django's site (I'll include a permalink below as well).
from django.shortcuts import render
def my_view(request):
# View code here...
return render(request, 'myapp/index.html', {"foo": "bar"},
content_type="application/xhtml+xml")
Django Documentation: Shortcut Functions : render

Related

django 3.1 multilanguage site breaks login

I have set up a django 3.1 site that uses 2 languages, English and German, and I use i18n_patterns in my urls.py. The problem is, in my views.py method, I never get a POST request, even though I specify method="POST" in my form. It always comes in as a GET request, and I cannot login. Somewhere along the way, the system changes my POST request into a GET request.
urlpatterns = []
urlpatterns += i18n_patterns(
path('{}/'.format(settings.DJANGO_ADMIN_URL), admin.site.urls),
path('review/', include('review.urls')),
path('anmelden_success/', views.anmelden_success, name='anmelden_success'),
path('', views.site_login, name='site_login'),
path('site_login/', views.site_login, name='site_login'),
path('site_logout/', views.site_logout, name='site_logout'),
)
I log in with this form, specifying method="POST":
<form action="/site_login/" method="POST" id="login-form">{% csrf_token %}
<label class="required" for="id_username">Benutzer:</label> <input type="text" name="username" autofocus required id="id_username">
<label class="required" for="id_password">Passwort:</label> <input type="password" name="password" required id="id_password">
<input type="hidden" name="next" value="/review/">
<label> </label><input type="submit" value="Anmelden">
</form>
The request comes to my views.py method site_login:
def site_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/anmelden_success')
else:
return HttpResponse("Sorry, you failed to login.")
else:
if request.user.is_authenticated:
return redirect('/review')
else:
return render(request, 'registration/login.html')
Since it somehow gets changed from a POST request to a GET request, my login fails, and I come straight back to my login page with the /de/ (or /en/) prepended: /de/site_login
If I remove i18n_patterns from my urls.py, I can login using the POST request.
urlpatterns = [
path('{}/'.format(settings.DJANGO_ADMIN_URL), admin.site.urls),
path('review/', include('review.urls')),
path('anmelden_success/', views.anmelden_success, name='anmelden_success'),
path('', views.site_login, name='site_login'),
path('site_login/', views.site_login, name='site_login'),
path('site_logout/', views.site_logout, name='site_logout'),
]
#urlpatterns += i18n_patterns()
With this urls.py config, I can login. But I have lost the multiple language functionality.
How can I have both?
Thanks in advance for any tips.
try to add url like this <form action="{% url 'site_login' %}"> in your form instead of <form action="/site_login/">

how create a login and registration page for a website using django framework?

I am new to Django. i am unable to store the user input values into the postgres DB. I have created a tables using Models.py file and create a user interface using template file .How can i pass the vaues to the database using view.py file . someone help me plsz
For simple log-in
in users/views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, logout,login
from django.http import HttpResponse, HttpResponseRedirect
def user_login(request):
if request.method == "POST":
phone = request.POST.get('phone')
password = request.POST.get('password')
user = authenticate(username=phone, password=password)
if user:
login(request,user)
return HttpResponseRedirect('/users/home')
else:
error = " Sorry! Phone Number and Password didn't match, Please try again ! "
return render(request, 'login/index.html',{'error':error})
else:
return render(request, 'login/index.html')
and in template login/index.html
<html>
<body>
{% if error %}
{{ error }}
{% endif %}
<form method="post" action="/users/login/">{% csrf_token %}
<input type=text placeholder="PhoneNo" name="phone">
<input type=password placeholder="Password" name="password">
<input type="submit" value="login">
</body>
</html>
for registration
login/signup.html
<html>
<body>
<form method=post action="users/signup/">{% csrf_token %}
<input type="text" name="phone" placeholde="Phone No">
<input type="text" name="email" placeholde="Email">
<input type="text" name="password1" placeholde="Password">
<input type="text" name="password2" placeholde="Password Again">
<input type="submit" value="signup">
</form>
</body>
</html>
in users/views.py
def users_signup(request):
if request.method == 'POST':
email = request.POST.get('email')
phone = request.POST.get('phone')
pass_1 = request.POST.get('password1')
pass_2 = request.POST.get('password2')
if pass_1 == pass_2:
user = User.objects.create_user(
username=phone,
email=email,
password=pass_1,
)
return HttpResponseRedirect("/")
else:
error = " Password Mismatch "
return render(request, 'login/signup.html',{"error":error})
else:
return render(request, 'login/signup.html')
main urls.py in main project folder where there is settings.py file would be
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^users/', include('users.urls')),
]
also url.py of app say "users"
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^login/', "users.views.user_login", name='login_url'),
url(r'^signup/', "users.views.user_signup", name='signup_url'),
)
Assuming your UI is based on a form, all you need to do in view.py is to handle a POST request which is sent from client when this form is submitted. So you define a method (say signup) which would get passed a request and possibly other parameters if needed. In it you do necessary validation (i.e. check if this user already exists) and return either new page with error messages via render() or a redirect to the next page if all is good.
More details in official tutorial which is quite good as correctly pointed out by #anuragal

Django Form request.POST.get() always returns empty

Sorry if this is a noob question. I'm creating a login form for a Django app, but I'm having trouble getting it to work. request.POST.get() doesn't return anything, so the authentication always fails. Am I missing something obvious?
login.html:
{% extends "base.html" %}
{% block content%}
<h2>Welcome! Please login to continue.</h2> <br>
<form action="{% url 'account:authenticate' %}" method="post">
{% csrf_token %}
<div >
<label for='username'> Username: </label>
<input type='text' name='Username' id='username'> <br><br>
<label for='password'>Password: </label>
<input type='password' name='Password' id='password'><br><br>
<input type='submit' value='Login'>
</div>
</form>
relevant part of views.py:
from django.shortcuts import render, get_object_or_404
from datetime import datetime
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.template import loader
from random import randrange
from django.contrib.auth import authenticate
def login(request):
return render (request, 'login.html')
def authenticate(request):
usern = request.POST.get('username', '')
passw = request.POST.get('password', '')
user = authenticate(username = usern, password = passw)
if user is not None:
authenticate.login(request, user)
return HttpResponseRedirect('/voters/instructions')
else:
return HttpResponseRedirect('/account/loginfail')
def loginfail(request):
return render (request, 'loginfail.html')
I'm using Django 1.10. Thanks!
Check out the names in the form input fields they are case sensitive. in Django do this
usern = request.POST.get('Username', '')
passw = request.POST.get('Password', '')
or in html form make them lowercase the input name field

how to use Django redirect to the original request after login

I practice how to use django login , but it can't redirect to the page before login
Please teach me how to do it Thank you very much
My project name is :proj
And I have an app name: app1
when I go to http://127.0.0.1:8000/f/index/ it will redirect to http://127.0.0.1:8000/accounts/login/?next=/f/index/
and after I enter the username and password,
I want to redirect to http://127.0.0.1:8000/f/index/ ( by the parameter ?next=/f/index/) but don't know how to do .
app1/views.py :
from django.contrib.auth.decorators import login_required
#login_required
def index(request):
logger.info('test')
....
proj/urls.py:
urlpatterns = patterns('',
url(r'^accounts/login/$', 'proj.views.login'),
url(r'^accounts/logout/$', 'proj.views.logout'),
url(r'^accounts/auth/$', 'proj.views.auth_view'),
proj/views.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
def login(request):
c={}
c.update(csrf(request))
return render_to_response('proj/login.html',c)
def auth_view(request):
username = request.POST.get('username','')
password = request.POST.get('password','')
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
# return HttpResponseRedirect(request.POST.get('next')) #not work
else:
return HttpResponseRedirect('/accounts/invalid')
proj/login.html:
{% if form.errors %}
<p class="error">Sorry.that's not valid </p>
{% endif %}
<form action="/accounts/auth/?next={{ request.get_full_path|urlencode }}" method="post">{% csrf_token %}
<label for="username" >User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password" >Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
</form>
try this in views.py:
if user is not None:
auth.login(request,user)
return HttpResponseRedirect('/f/index/')
when you type url, and you are not login before, and django redirect to the url :http://127.0.0.1:8000/accounts/login/?next=/f/index/
after entering your username and password, and click submit button, django redirect you automatically to http://127.0.0.1:8000/f/index/
using URLresolver.

Django Python redirect after login

I know this questions has been answered is one ore another way, but I still cant figure out how to redirect after a user is logged in. I know Django comes with built in websites, but I need a custom login form, which looks like this(this is the HTML):
{% if user.is_authenticated %}
<!-- Authenticate account menu -->
{% else %}
<h3>Login</h3>
<form action="/app/login/" method="post" accept-charset="utf-8">
<label for="username">Username</label>
<input type="text" name="username" value="" id="username" />
<label for="password">Password</label>
<input type="password" name="password" value="" id="password" />
<p><input type="submit" value="Login →"></p>
</form>
{% endif %}
My views.py looks like that:
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import Context, loader
from django.contrib.auth import authenticate, login
from django.views.generic.simple import *
def index(request):
if request.method == 'POST':
user = authenticate(username=request.POST['username'], password=request.POST['password'])
if user is not None:
if user.is_active:
login(request, user)
# success
if request.POST['next']:
return HttpResponseRedirect(request.POST['next'])
else:
return HttpResponseRedirect('/')
else:
# disabled account
return direct_to_template(request, 'inactive_account.html')
else:
# invalid login
return render_to_response("app/index.html")
return render_to_response("app/index.html")
I did not write the code myself entirely. I figured out that the redirect happens in the html file some where here: <form action="/app/login/. But django says it cant find the url. All in all I have to say I am new to web programming+django+python and not totally clear on the concept.
Thanks for help!!
After login(request, user) you need to return some http response, for example it's a page rendered from ome template. But if you want to go to some other page, you can return HttpResponseRedirect('/needed_url') and you'll get a request to pointed url.
Also you can point request.POST['referrer']) as needed url to go to previous page.
Django Docs - HttpResponseRedirect
P.S. In addition I can say the <form action="/some/url/" ... points what address you will go to manage you form data. In case with Django you should have a record in your urls.py file like (r'^some/url/$', some_function), which will handle you request with specified function.

Categories