POST method always return 403 Forbidden

前端 未结 7 1692
走了就别回头了
走了就别回头了 2021-02-19 01:46

I have read Django - CSRF verification failed and several questions (and answers) related to django and POST method. One of the best-but-not-working-for-me answer is https://sta

相关标签:
7条回答
  • 2021-02-19 01:57

    You also can use

    direct_to_template(request, 'library/search.html', result) 
    

    instead of

    render_to_response('library/search.html', result, context_instance=RequestContext(request))
    

    because direct_to_template adds RequestContext automatically. But note that direct_to_template is going to be deprecated and django offers to use CBV TemplateView instead.

    RequestContext allows you to use context processors. And this is your mistake: {% csrf_token %} outputed empty string and you got 403.

    0 讨论(0)
  • 2021-02-19 02:00

    The response is 403 bcoz, django requires a csrf token (included in the post data) in every POST request you make.

    There are various ways to do this such as:

    Acquiring the token from cookie and the method has been explained in article enter link description here

    or

    You can access it from DOM using {{ csrf_token }}, available in the template

    So now using the second method:

    var post_data = {
      ...
      'csrfmiddlewaretoken':"{{ csrf_token }}"
      ...
    }
    $.ajax({
      url:'url',
      type:'POST'
      data:post_data,
      success:function(data){
        console.log(data);
      },
      error:function(error){
        console.log(error);
      }
    });
    
    0 讨论(0)
  • 2021-02-19 02:03

    You need to use RequestContext with your response

    for example in view.py file

    from django.template import RequestContext
    
    def home(request):
        return render_to_response('home.html',RequestContext(request, {}))
    
    0 讨论(0)
  • 2021-02-19 02:04

    Try putting RequestContext in the search_form view's render_to_response:

    context_instance=RequestContext(request)
    
    0 讨论(0)
  • 2021-02-19 02:12

    The easiest way to avoid such problems is to use the render shortcut.

    from django.shortcuts import render
    # .. your other imports
    
    def search_form(request):
        return render(request, 'library/search_form.html')
    
    def search(request):
        q = request.GET.get('q')
        results = BookModel.objects.all()
        if q:
            results = results.filter(title__icontains=q)
        return render(request, 'library/search.html', {'result': results})
    
    0 讨论(0)
  • 2021-02-19 02:14

    This answer is for people that may encounter this same problem in the future.

    The CSRF {{csrf_token}} template tag that is required for forms in Django prevent against Cross Site Request Forgeries. CSRF makes it possible for a malicious site that has been visited by a client's browser to make requests to your own server. Hence the csrf_token provided by django makes it simple for your django server and site to be protected against this type of malicious attack. If your form is not protected by csrf_token, django returns a 403 forbidden page. This is a form of protection for your website especially when the token wasn't left out intentionally.

    But there are scenarios where a django site would not want to protect its forms using the csrf_token. For instance, I developed a USSD application and a view function is required to receive a POST request from the USSD API. We should note that the POST request was not from a form on the client hence the risk of CSRF impossible, since a malicious site cannot submit requests. The POST request is received when a user dials a USSD code and not when a form is submitted.

    In other words, there are situations where a function will need to get a POST request and there would not be the need of {{csrf_token}}.

    Django provides us with a decorator @csrf_exempt. This decorator marks a view as being exempt from the protection ensured by the middleware.

    from django.views.decorators.csrf import csrf_exempt
    from django.http import HttpResponse
    
    @csrf_exempt
    def my_view(request):
        return HttpResponse('Hello world')
    

    Django also provides another decorator that performs the same function with {{csrf_token}}, but it doesn't reject incoming request. This decorator is @requires_csrf_token. For instance:

    @requires_csrf_token
    def my_view(request):
        c = {}
        # ...
        return render(request, "a_template.html", c)
    

    The last decorator that will be mentioned in this post does exactly the same thing as {{csrf_token}} and it is called @csrf_protect. However, the use of this decorator by itself is not best practice because you might forget to add it to your views. For instance:

    @csrf_protect
    def my_view(request):
        c = {}
        # ...
        return render(request, "a_template.html", c)
    

    Below are some links that will guide and explain better.

    https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#module-django.views.decorators.csrf

    https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/

    http://www.squarefree.com/securitytips/web-developers.html#CSRF

    0 讨论(0)
提交回复
热议问题