how to implement csrf without csrf token in django - python

In django, if I want to use csrf token, I need to imbed a form with csrf token in django template. However as a backend-engineer I am co-working with a front-end engineer whose code is not available for me. So I caanot use the template. In this case, if I want still the csrf function. what should I do?

you should ask the coworker to embed the csrf token in the form he is sending you
you can get it from document.Cookies if he doesnt want to or cannot use the {% csrf %} tag

You may use #csrf_exempt decorator to except csrf tokens.
First, import decorator
from django.views.decorators.csrf import csrf_exempt
Then add #csrf_exempt before your view.
#csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
More details can be found here enter link description here

Related

How can I make Django user logout without a new url page?

For logout I am using ready django.contrib.auth.LogoutView and everyone in their tutorials are creating a new url for example '/logout' and my question is how can I use that view without a new url page and html template? Plese use some code for views.py in your answers ;)
If you don't want any redirects at all and want to stay on the same page, like when you send an AJAX request then you can write your own view like this:
from django.contrib.auth import logout
from django.http import HttpResponse
def logout_view(request):
logout(request)
return HttpResponse('OK')
You don't have to route the /logout url to a template. You can redirect it to whatever page you want by using the next_page attribute (docs).
You can also look into setting a LOGOUT_REDIRECT_URL: https://docs.djangoproject.com/en/3.1/ref/settings/#logout-redirect-url.

How to connect Django Rest Framework with contrib.auth views

I am using DRF with JWT (JSON Web Token) authentication. I want to use django's built-in reset password functionality. So, I have included the urls:
url('^', include('django.contrib.auth.urls')),
But, of course, under an API, calling https://.../password_reset/ results on a csrf token missing error. I am wondering which aproach should I take to solve this. Should I change the built in reset_password view and remove csrf protection? Is it a better idea to create a DRF endpoint that accepts the email (reset_password view post parameter) and then somehow generate a csrf token and send it to the view with redirect(reverse("reset_password"), email=email) ... but then, redirect will not send a post request to the reset_password view. Maybe saving the email to session? Any advice will help.
I think in the case of a password reset endpoint it is safe to remove CSRF protection. CSRF protection is for authenticated endpoints to prevent other websites from using a user's stored credentials to gain unauthorized access. Since the PasswordResetForm used by Django doesn't do anything other than send an e-mail, an attacker can't really do much other than annoy a user by spamming them with password reset emails.
You could use a third party for this, but if all you're doing is adding a password reset endpoint, you just need a few lines of code.
views.py
import json
from django.contrib.auth.forms import PasswordResetForm
from django.http.response import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
#csrf_exempt
#require_http_methods(['POST'])
def email_password_reset(request):
# the POST body should be in the format {'email': 'user#user.com'}
try:
# you could also uncomment the following line if you wanted this view to be anonymous only
# assert not request.user.is_authenticated()
assert request.META.get('CONTENT_TYPE', '') == 'application/json'
body = json.loads(request.body)
except (AssertionError, TypeError):
pass
else:
form = PasswordResetForm(body)
if form.is_valid():
form.save()
finally:
return HttpResponse(status=200)
urls.py
urlpatterns = patterns(...
url(r'^/api/password_reset/$', 'email_password_reset', name='email-password-reset')
...)

django authorization without using request.user.is_authenticated()

I am working on django website and I am using django Auth for user authentication and for authorization of user i am using request.user.is_authenticated() code in django view but using this i have to write this code in each and every view, because in my site there is only homepage, registration page and login page which can be accessed without login. So in each and every view i have to right this code.
def dashboard(request):
if request.user.is_authenticated():
return render(request, 'home/dashboard.py')
else:
return HttpResponse('User is not logged In')
That's why I want to ask is there any way to write code only once for all views those can not be accessed without login as we do in CakePHP using authcomponent.
Yes, just use the login_required decorator or LoginRequiredMixin
from django.contrib.auth.decorators import login_required
#login_required
def dashboard(request):
return render(request, 'home/dashboard.py')
from django.contrib.auth.mixins import LoginRequiredMixin
class MyCBV(LoginRequiredMixin, GenericView):
What this will do is redirect anyone attempting to access the view back to the LOGIN_URL (which can be overridden here) with a next get parameter back to the view, so that they must login before continuing. This isn't the same as what you currently do, but its much friendlier
If your entire website needs to be logged in, then you can use a middleware to make this the default
You can use #login_required instead. See here

Differing Reponse Codes from Django Application

For both GET and POST requests I simply want to print the associated QueryDict in my test view:
if request.method == 'GET':
print request.GET
if request.method == 'POST':
print request.POST
When I make requests using both methods I get different response codes. I could use some help.
The post request has triggered Django's CSRF protection so you are getting a 403 Forbidden response.
Usually, it means that you need to include the CSRF template in your template.
In this case, because you are making requests from the shell, it might be appropriate to use the csrf_exempt decorator on this view to disable the CSRF protection.

Persistent "CSRF token missing or incorrect.". Jinja and django-registration setup

I receive this message:
CSRF token missing or incorrect.
In most forums, the tell you to get the {% csrf_token %} in the form, and i do have it.
Also i have in my settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.csrf",
"django.contrib.auth.context_processors.auth",
)
I am using jinja, which didn't seem to use CSRF, but then i installed django registration and i got lost, since, it seems to be using some other views, that i don't have access to so to say, they are not written by me, and i can't figure out where they are. "standard auth views" as they call them. So i am unable to add "RequestContext".
Any ideas what's going on and how I can get it going? thanx
You might have to rewrite the django-registration view manually. Looks like there's an issue with how Jinja likes to do things and how Django wants to configure template loaders..
To look at the standard auth views, just look under "site-packages" in your python installation.
You could try wrapping the standard auth views like this:
from django.contrib.auth.views import login, logout
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def my_wrapped_login_view(request):
return login(request)
#csrf_protect
def my_wrapped_logout_view(request):
return logout(request)
I basically imported Django's standard auth views and called them with my own, which have the csrf_protect decoration. It's worth a shot.
Have you also got the standard Django Templating system installed? That will be required for most apps that are distributed with templates.
For CSRF, a context processor inserts the variable 'csrf_token' into the response context that it retrieves from the middleware if enabled. Now all you have to do, is make sure that it's apart of your form.
This is straight out of django.core, and is subject to change at any time.
if csrf_token:
if csrf_token == 'NOTPROVIDED':
return mark_safe(u"")
else:
return mark_safe(u"<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='%s' /></div>" % csrf_token)
However, seeing that, all you really need to know is that you have to have an input type named csrfmiddlewaretoken with the value of context.get('csrf_token','') within your form and that's all she wrote.
This answer isn't specific to django-registration, but just using Django with Jinja2 in general.
Django's CsrfViewMiddleware sets the csrf_token cookie if it determines that you have accessed the csrf_token context member. Unfortunately, Jinja2 rendering doesn't occur until after Django's middleware executes. As a result, the cookie doesn't get set, and therefore does not match the form, and you will get the 403 error.
To get around this issue, you need to access context['csrf_token'] at some point before you finish processing the response.
If you're using class-based views, you can create a CsrfProtectMixin:
class CsrfProtectMixin(object):
def render_to_response(self, context, **response_kwargs):
# Csrf processing happens when using a RequestContext.
# Be sure to use one.
if not isinstance(context, RequestContext):
context = RequestContext(self.request, context)
# Force access to csrf_token due to the way jinja2 renders the template
# after middleware has finished processing. Otherwise, the csrf cookie
# will not be set.
str(context.get('csrf_token'))
return super(CsrfProtectMixin, self).render_to_response(context, **response_kwargs)
And then in your view class:
class MyView(CsrfProtectMixin, TemplateView):
def get(self, request, *args, **kwargs):
context = {}
return self.render_to_response(context)
If you're not using class-based views, you can do something like:
def my_view(request):
context = RequestContext(request)
str(context['csrf_token']) #force access to the csrf_token
return render_to_response('template.html', context)
Or perhaps monkey patch render_to_reponse with the logic in the class, above.
The most straightforward answer to this one is to just put {% csrf_token %} within the form tag in your template/html.
I just switched off the csrf middleware in the settings like so, and now it works:
#'django.middleware.csrf.CsrfViewMiddleware',

Categories