使用Python requests发请求时如何通过Django的csrf_token验证
问题原因
Django的CSRF验证逻辑要求同时满足两个条件:
- Cookie中携带正确的
csrftoken值 - 请求体/请求头中显式传递相同的CSRF令牌值
你当前只传递了Cookie中的csrftoken,缺少第二个校验参数,所以触发403错误。你Django代码中调用get_token(request)的逻辑是正确的,该方法会自动为响应设置合法的csrftokenCookie。
解决方案
有两种常用的验证方式,二选一即可:
方式1:POST表单中添加csrfmiddlewaretoken参数
直接在POST提交的表单数据中加入CSRF令牌字段,修改后的请求代码如下:
import requests url = "http://192.168.0.102:8000/home/" data = {"a":"5", "b":4} # 先GET请求获取csrftoken resp_get = requests.get(url) # 从返回的Cookie中提取csrftoken,加入POST表单参数 data['csrfmiddlewaretoken'] = resp_get.cookies['csrftoken'] # 发送POST请求,携带Cookie和带令牌的表单数据 resp_post = requests.post(url, cookies=resp_get.cookies, data=data)
方式2:请求头添加X-CSRFToken字段
如果提交的是JSON格式数据,或者不想修改表单参数,可以在请求头中传递令牌:
import requests url = "http://192.168.0.102:8000/home/" data = {"a":"5", "b":4} resp_get = requests.get(url) headers = { "X-CSRFToken": resp_get.cookies['csrftoken'] } # 提交JSON数据也可以用这个方式 resp_post = requests.post(url, cookies=resp_get.cookies, json=data, headers=headers)
额外优化建议
推荐使用requests.Session()复用连接,自动管理Cookie,不用手动传递Cookie参数,使用示例:
import requests session = requests.Session() url = "http://192.168.0.102:8000/home/" resp_get = session.get(url) data = {"a":"5", "b":4, "csrfmiddlewaretoken": session.cookies['csrftoken']} resp_post = session.post(url, data=data)
如果你的服务部署在HTTPS环境下,需要确保请求携带正确的Referer头,否则Django会额外拦截请求。
内容的提问来源于stack exchange,提问作者M.H RONY
相关产品推荐
相关产品推荐

