我有一个django服务器上传文件,当我使用浏览器时,我可以毫无问题地上传文件.
但是,如果我使用python-requests命令,它会告诉我CSRF验证失败.请求中止.python请求代码如下:
#upload via HTTP
file = {"docfile": open(fullfilename, "rb")}
s = requests.Session()
r = s.get(dhost)
r = s.post(dhost, files=file)
Run Code Online (Sandbox Code Playgroud)
如果我执行我的代码,我得到代码403并且错误CSRF验证失败.请求中止.失败原因:CSRF令牌丢失或不正确.
但是,如果我查看我发送的标题,我会设置cookie:
CaseInsensitiveDict({'Content-Length': u'84169',
'Accept-Encoding': 'gzip, deflate, compress',
'Accept': '*/*',
'User-Agent': 'python-requests/2.0.1 CPython/2.7.3 Linux/3.6.11+',
'Cookie': 'csrftoken=GOOIsG89i5oMCJO6594algTXooxoUeoL',
'Content-Type': 'multipart/form-data; boundary=86ada00b4f6c41d5997293cce7a53b6b'})
Run Code Online (Sandbox Code Playgroud)
你能否告诉我应该做些什么才能让它发挥作用?
谢谢,
约翰.
yuv*_*uvi 16
它实际上一切正常,你只需要了解csrf的工作原理.当您在浏览器中加载页面时,会在内部获得一个csrf令牌{% csrf_token %}.因此,当您将数据发送到服务器时,您还会发送csrf令牌.
当您使用请求时,您会在"获取"部分获取Cookie,但您不会将其与"帖子"一起发送.没有它,你只是发送一个没有令牌的帖子请求,这意味着CSRF验证错误.要解决它,请尝试以下代码:
file = {"docfile": open(fullfilename, "rb")}
s = requests.Session()
r1 = s.get(dhost)
csrf_token = r1.cookies['csrftoken']
r2 = s.post(dhost, files=file, data={'csrfmiddlewaretoken': csrf_token}, headers=dict(Referer=dhost))
Run Code Online (Sandbox Code Playgroud)
如果这仅供您自己使用,您可以使用csrf_exampt在该视图上禁用csrf:
@csrf_exempt
def my_view(request):
...whateva...
Run Code Online (Sandbox Code Playgroud)
但请注意,如果您计划启动服务器并向公众开放,则不建议使用此解决方案
小智 -1
这取决于你想做什么。
如果不需要 CSRF 验证,可以使用 csrf_exempt 装饰器。
或者您可以创建一个新的 csrf_exempt 视图,仅用于通过 python 请求进行访问。