CSRF令牌在第二个post Django Rest框架上失败
我有一个问题,我可以成功登录,但任何后续请求显示为CSRF令牌在第二个post Django Rest框架上失败,django,django-rest-framework,python-requests,Django,Django Rest Framework,Python Requests,我有一个问题,我可以成功登录,但任何后续请求显示为 "detail":"CSRF Failed: CSRF token missing or incorrect." 我不知道我做错了什么,我查看了请求文档、DRF文档,关闭了验证url的身份验证,并搜索了关于该主题的旧SO帖子 这是一个基本功能,附带基本信息 def will_fail(): CURRENT_URL = 'http://127.0.0.1:8000/{}' session = requests.Session()
"detail":"CSRF Failed: CSRF token missing or incorrect."
我不知道我做错了什么,我查看了请求文档、DRF文档,关闭了验证url的身份验证,并搜索了关于该主题的旧SO帖子
这是一个基本功能,附带基本信息
def will_fail():
CURRENT_URL = 'http://127.0.0.1:8000/{}'
session = requests.Session()
response = session.get(CURRENT_URL.format('api-auth/login/'))
csrftoken = response.cookies['csrftoken']
first_response = session.post(CURRENT_URL.format('api-auth/login/'),
data={'username': 'itsme', 'password': 'password'},
headers={'X-CSRFToken': csrftoken})
response = session.post(CURRENT_URL.format('api-v1/languages/'),
params={'name': "French", "audio_base": "adpifajsdpfijsdp"},
headers={'X-CSRFToken': csrftoken})
第一次响应(登录):
这里是URL信息,也是非常通用的
from training.views import LanguageViewSet, PhraseViewSet, PhraseStatsViewSet
router = DefaultRouter()
router.register(r'languages', LanguageViewSet)
router.register(r'phrases', PhraseViewSet)
router.register(r'stats', PhraseStatsViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-v1/', include(router.urls, namespace='api'))
]
我使用的是ModelSerializer和ModelViewSet,我没有覆盖任何方法,而是包含所有字段
编辑:
我已经尝试过更新令牌,但它给了我一个关键错误-
Traceback (most recent call last):
File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 70, in <module>
will_fail()
File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 62, in will_fail
csrftoken = first_response.cookies['csrftoken']
File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 329, in __getitem__
return self._find_no_duplicates(name)
File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 400, in _find_no_duplicates
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
KeyError: "name='csrftoken', domain=None, path=None"
回溯(最近一次呼叫最后一次):
文件“C:/Users/Me/PycharmProjects/proj/post_data.py”,第70行,在
你会失败吗
文件“C:/Users/Me/PycharmProjects/proj/post_data.py”,第62行,将失败
csrftoken=第一个响应.cookies['csrftoken']
文件“C:\Users\Me\Envs\proj\lib\site packages\requests\cookies.py”,第329行,在\uu getitem中__
返回self.\u查找\u无重复项(名称)
文件“C:\Users\Me\Envs\proj\lib\site packages\requests\cookies.py”,第400行,在“无重复项”中
raise KeyError('name=%r,domain=%r,path=%r%%(name,domain,path))
KeyError:“name='csrftoken',domain=None,path=None”
您可能没有在请求中使用会话,这将保留下一个请求的初始响应cookie
DRF在上向您详细介绍了CSRF如何与DRF一起工作问题在于您的第一个请求让用户登录。Django在您登录时旋转令牌: 为什么用户在登录后会遇到CSRF验证失败? 出于安全原因,每次用户登录时都会轮换CSRF令牌。任何在登录之前生成表单的页面都会有一个旧的、无效的CSRF令牌,需要重新加载。如果用户在登录后使用“后退”按钮,或者在其他浏览器选项卡中登录,则可能会发生这种情况 您在下一个请求中使用的令牌是在轮换之前使用的令牌。您需要在登录请求之后从cookie中获取新令牌 最重要的是,
请求
透明地遵循重定向,并返回最后一个响应。因为第二个响应(可能)不使用令牌,所以它没有设置为cookie。您可以使用allow_redirects=False
获取第一个请求,然后从该请求获取新令牌。或者,您可以发送一个新的GET
请求,请求使用响应正文中的令牌的页面,然后令牌也将作为cookie发送
...
first_response = session.post(CURRENT_URL.format('api-auth/login/'),
data={'username': 'itsme', 'password': 'password'},
headers={'X-CSRFToken': csrftoken},
allow_redirects=False)
# Get the new token
newcsrftoken = first_response.cookies['csrftoken']
response = session.post(CURRENT_URL.format('api-v1/languages/'),
params={'name': "French", "audio_base": "adpifajsdpfijsdp"},
headers={'X-CSRFToken': newcsrftoken})
我不确定我是否理解,我是否使用了错误的会话?我发出get请求以提取csrf令牌,然后将其传递到后续post请求中。
from training.views import LanguageViewSet, PhraseViewSet, PhraseStatsViewSet
router = DefaultRouter()
router.register(r'languages', LanguageViewSet)
router.register(r'phrases', PhraseViewSet)
router.register(r'stats', PhraseStatsViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-v1/', include(router.urls, namespace='api'))
]
Traceback (most recent call last):
File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 70, in <module>
will_fail()
File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 62, in will_fail
csrftoken = first_response.cookies['csrftoken']
File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 329, in __getitem__
return self._find_no_duplicates(name)
File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 400, in _find_no_duplicates
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
KeyError: "name='csrftoken', domain=None, path=None"
...
first_response = session.post(CURRENT_URL.format('api-auth/login/'),
data={'username': 'itsme', 'password': 'password'},
headers={'X-CSRFToken': csrftoken},
allow_redirects=False)
# Get the new token
newcsrftoken = first_response.cookies['csrftoken']
response = session.post(CURRENT_URL.format('api-v1/languages/'),
params={'name': "French", "audio_base": "adpifajsdpfijsdp"},
headers={'X-CSRFToken': newcsrftoken})