Django:CSRF令牌丢失或不正确

时间:2021-07-01 04:53:52

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. I have tried specifying localhost:8000 as stated in someone else's question but this did not work for me. I am trying to have a file upload form but I am receiving an error that form.py does not have the CSRF token.

我有django的1.3版本。我已经尝试过指定localhost:8000,如其他人的问题所述,但这对我不起作用。我试图有一个文件上传表单,但我收到一个错误,form.py没有CSRF令牌。

form.py:

form.py:

class UploadFileForm(forms.Form):

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

views.py:

views.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:

upload.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

我很难过,请告诉我一些尝试的事情。谢谢

3 个解决方案

#1


30  

You need to pass RequestContext in render_to_response for csrf_token

您需要在render_to_response中为csrf_token传递RequestContext

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的标记传递给模板。

#2


1  

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)

P.S. Make sure you have the below line in your MIDDLEWARE variable in the settings.py

附:确保settings.py中的MIDDLEWARE变量中包含以下行

'django.middleware.csrf.CsrfViewMiddleware'

#3


0  

It can also happen if you use @cache_page(60 * 15) decorators. If you cache a page with a form containing a CSRF token, you'll cache the CSRF token of the first user only. So it's kinda hard to debug sometimes.

如果使用@cache_page(60 * 15)装饰器,也会发生这种情况。如果使用包含CSRF令牌的表单缓存页面,则只缓存第一个用户的CSRF令牌。所以有时很难调试。

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. This means that the middleware will play well with the cache middleware if it is used as instructed (UpdateCacheMiddleware goes before all other middleware).

如果模板使用csrf_token模板标记(或者以其他方式调用get_token函数),则CsrfViewMiddleware将向响应中添加cookie和Vary:Cookie标头。这意味着如果按照指示使用(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. 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中间件将无法设置Vary标头或CSRF cookie,并且响应将在没有任何一个的情况下进行缓存。在这种情况下,在任何需要插入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):
    ...

#1


30  

You need to pass RequestContext in render_to_response for csrf_token

您需要在render_to_response中为csrf_token传递RequestContext

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的标记传递给模板。

#2


1  

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)

P.S. Make sure you have the below line in your MIDDLEWARE variable in the settings.py

附:确保settings.py中的MIDDLEWARE变量中包含以下行

'django.middleware.csrf.CsrfViewMiddleware'

#3


0  

It can also happen if you use @cache_page(60 * 15) decorators. If you cache a page with a form containing a CSRF token, you'll cache the CSRF token of the first user only. So it's kinda hard to debug sometimes.

如果使用@cache_page(60 * 15)装饰器,也会发生这种情况。如果使用包含CSRF令牌的表单缓存页面,则只缓存第一个用户的CSRF令牌。所以有时很难调试。

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. This means that the middleware will play well with the cache middleware if it is used as instructed (UpdateCacheMiddleware goes before all other middleware).

如果模板使用csrf_token模板标记(或者以其他方式调用get_token函数),则CsrfViewMiddleware将向响应中添加cookie和Vary:Cookie标头。这意味着如果按照指示使用(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. 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中间件将无法设置Vary标头或CSRF cookie,并且响应将在没有任何一个的情况下进行缓存。在这种情况下,在任何需要插入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):
    ...