简体   繁体   English

Django:CSRF 令牌丢失或不正确

[英]Django: CSRF token missing or incorrect

The error is at location http://127.0.0.1:8000/fileupload/form.py错误位于http://127.0.0.1:8000/fileupload/form.py

I have version 1.3 of django.我有 Django 1.3 版。 I have tried specifying localhost:8000 as stated in someone else's question but this did not work for me.我曾尝试指定 localhost:8000 如其他人的问题中所述,但这对我不起作用。 I am trying to have a file upload form but I am receiving an error that form.py does not have the CSRF token.我正在尝试使用文件上传表单,但我收到一个错误,即 form.py 没有 CSRF 令牌。

form.py:表单.py:

class UploadFileForm(forms.Form):

    title = forms.CharField(max_length=50)
    file  = forms.FileField()

views.py:视图.py:

def upload_file(request):

    c = {}
    c.update(csrf(request))

    if (not request.user.is_authenticated()) or (request.user == None):
      return HttpResponseRedirect("/?error=11")


    if request.method == 'POST':
      form = c['UploadFileForm'] = UploadFileForm(request.POST, request.FILES,  c, context_instance=RequestContext(request))

      if c['UploadFileForm'].is_valid():
        handle_uploaded_file(request.FILES['file'])
        return HttpResponseRedirect('/success/url/')

    else:
        form = c['UploadFileForm'] = UploadFileForm()
    return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']})

upload.html:上传.html:

{% block main_content %}


  <form action="fileupload/form.py" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    <table>

      <tr><td>Title:</td><td><input type="text" name="title" /></td></tr>
      <tr><td>File:</td><td><input type="file" name="file" /></td></tr>
    </table>
      <input type="submit" value="Submit" class = "float_right button_input" />

  </form> 

{% endblock main_content %}

I am very stumped please tell me some things to try.我很难过,请告诉我一些要尝试的事情。 Thank You谢谢你

You need to pass RequestContext in render_to_response for csrf_token你需要传递RequestContext在为选择render_to_response csrf_token

For this : ( views.py )为此:( views.py

from django.template import RequestContext

...

return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']},  RequestContext(request))
# Added RequestContext

This passes the token for csrf to the template.这会将 csrf 的令牌传递给模板。

It can also happen if you use @cache_page(60 * 15) decorators.如果您使用@cache_page(60 * 15)装饰器,也会发生这种情况。 If you cache a page with a form containing a CSRF token, you'll cache the CSRF token of the first user only.如果您使用包含 CSRF 令牌的表单缓存页面,您将仅缓存第一个用户的 CSRF 令牌。 So it's kinda hard to debug sometimes.所以有时候调试有点困难。

More info from Django documentation来自Django 文档的更多信息

If the csrf_token template tag is used by a template (or the get_token function is called some other way), CsrfViewMiddleware will add a cookie and a Vary: Cookie header to the response.如果模板使用了csrf_token模板标记(或者get_token函数以其他方式调用), CsrfViewMiddleware将向响应添加一个 cookie 和一个Vary: Cookie标头。 This means that the middleware will play well with the cache middleware if it is used as instructed ( UpdateCacheMiddleware goes before all other middleware).这意味着,如果按照指示使用,中间件将与缓存中间件很好地配合使用( UpdateCacheMiddleware在所有其他中间件之前)。

However, if you use cache decorators on individual views, the CSRF middleware will not yet have been able to set the Vary header or the CSRF cookie, and the response will be cached without either one.但是,如果您在单个视图上使用缓存装饰器,CSRF 中间件将无法设置 Vary 标头或 CSRF cookie,并且响应将在没有任何一个的情况下被缓存。 In this case, on any views that will require a CSRF token to be inserted you should use the django.views.decorators.csrf.csrf_protect() decorator first:在这种情况下,在任何需要插入 CSRF 令牌的视图上,您​​应该首先使用django.views.decorators.csrf.csrf_protect()装饰器:

 from django.views.decorators.cache import cache_page from django.views.decorators.csrf import csrf_protect @cache_page(60 * 15) @csrf_protect def my_view(request): ...

My answer is similar to the @Yugal Jindle's answer above.我的回答类似于上面@Yugal Jindle 的回答。

I am using Django 1.10 and I had a similar issue, it worked for me after editing我正在使用 Django 1.10,我遇到了类似的问题,编辑后对我有用

return render_to_response(param1, param2)

to

return render(request, param1, param2)

PS Make sure you have the below line in your MIDDLEWARE variable in the settings.py PS 确保在 settings.py 中的 MIDDLEWARE 变量中有以下行

'django.middleware.csrf.CsrfViewMiddleware'

For my case, I use AJAX to post data to my views function, then the same error happens, so the easy method to solve it is to change the data from就我而言,我使用 AJAX 将数据发布到我的视图函数,然后发生了同样的错误,因此解决它的简单方法是将数据从

data:{ 'k':'v' }

To

data:{ 'k':'v' ,addcsrfmiddlewaretoken:'{{ csrf_token }}',}

because we manually add a csrf-token, so it is not missing or incorrect.因为我们手动添加了一个 csrf-token,所以它不会丢失或不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM