使用django和postman {"detail":"CSRF失败:缺少或不正确的CSRF令牌。"}

16
我正在使用Postman检查Django-Rest-Framework返回的JSON响应。 当我第一次尝试通过POST方法将ID、电子邮件和密码发送到我的AWS(亚马逊网络服务)上的Django时,它运行良好。它返回了如下内容:
  {
    "key": "99def123123123123d88e15771e3a8b43e71f"
}

但在第一次尝试后,从第二次尝试开始,它返回了其他单词

{"detail":"CSRF Failed: CSRF token missing or incorrect."}

(此外编辑+) 我的Putty终端显示“POST /rest-auth/login/ HTTP/1.1” 403 58

我看到了http://kechengpuzi.com/q/s31108075,但不适用于我的情况。

http://django-rest-framework.narkive.com/sCyJk3hM/authentication-ordering-token-vs-session得知,我无法找到使用Postman的解决方案。

  1. 我应该如何正确使用Postman?

  2. 或者您可以推荐其他工具使用吗?

我正在使用Retrofit2制作Android应用程序,因此需要工具来检查POST、GET方法和响应。


你的意思是说在没有任何更改的情况下,两个请求之间得到了不同的结果吗? - Windsooon
是的,我在第一次尝试和其他尝试中使用POST方法发布了以下内容:{ "username": "thesamething", "email": "thesamething", "password": "thesamething" }。当我在从DRF(实际上是django-rest-auth)复制的给定DRF HTML页面上以相同方式使用POST方法时,没有发生此错误。但是在Postman上,它会出现错误。 - H.fate
你在请求中设置了 CARF 令牌吗? - Windsooon
我放置了Headers key : e0af91707f0434a1a2a7581dd3f4f48d3bdad717 或者 Authorization : e0af91707f0434a1a2a7581dd3f4f48d3bdad717 或者 Authorization : "key": "99def123123123123d88e15771e3a8b43e71f" 但是它不起作用。正如你所说,我认为我在使用header方面出错了。正确的放置授权密钥的方式是什么?我在哪里可以查看它? - H.fate
尝试在Postman中使用接收到的CSRF令牌设置X-CSRFToken标头(请参见https://dev59.com/N18d5IYBdhLWcg3wmDKf#52782448) - Peter F
8个回答

26

如果使用基于令牌的DRF身份验证,请不要忘记在settings.py中进行设置。否则,您将收到CSRF错误。

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ]
}

14

我也遇到了与 Postman 相同的问题。第一次获取令牌后,每个请求都被要求包含 CSRF。我意识到我启用了 Session 和 Token 认证方法,因此我注释掉了 SessionAuthentication 行(当然,您也可以删除它)。

'DEFAULT_AUTHENTICATION_CLASSES': [
    'rest_framework.authentication.TokenAuthentication',
    # 'rest_framework.authentication.SessionAuthentication',
]

之后,我可以仅使用我的凭据而不包括任何 CSRF 代码来请求令牌:

Successful token requests

我认为启用这两个身份验证类导致 Django 在某种程度上混淆了。


谢谢。可能是一个边缘情况,但我在从应用程序中剥离JWT令牌身份验证时遇到了这个问题,无法找出问题所在。 - Tyk

8
您的API需要CSRF令牌,您必须将CSRF令牌添加到请求(包括在Postman中):
data: { csrfmiddlewaretoken: csrf_token, "username": "thesamething", "email": "thesamething", "password": "thesamething" }

您可以从表单输入字段中获取CSRF令牌(如果您使用django内置的表单API,则会发现隐藏字段),或者如果您使用Ajax,则可以查看跨站请求伪造保护。这与您的授权密钥无关,您的密钥用于识别您的身份,而CSRF令牌则是为了确保此请求是从您的服务器发送的。


我需要在Postman的Body中添加data: { csrfmiddlewaretoken: csrf_token, "username": "thesamething", "email": "thesamething", "password": "thesamething" }吗?不需要更改Headers中的任何内容吗? - H.fate
尝试在Postman中使用接收到的CSRF令牌设置X-CSRFToken标头(请参见https://dev59.com/N18d5IYBdhLWcg3wmDKf#26639895) - Peter F

6

1

在settings.py文件中

INSTALLED_APPS = [
...
...
...
...
'rest_framework.authtoken',
...
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}


在项目的urls.py中。
from rest_framework.authtoken import views

urlpatterns = [
    ....
    path('api-token-auth/',views.obtain_auth_token,name='api-token-auth')

]

打开终端

$ pip3 install httpie
$ python3 manage.py createsuperuser # if not created
$ http POST http://localhost:8000/api-token-auth/ username="username" password = "password"   # You will get token key (Just copy it) ex:a243re43fdeg7r4rfgedwe89320

您的令牌密钥也将自动保存在您的数据库中

转到Postman标题 (如示例所示) 例如:从Postman截图,显示如何粘贴访问令牌 然后插入您的令牌密钥。

从此视频中获取令牌密钥的参考


0

我将请求方法从post改为patch,然后就能够登录了


0
创建一个返回HTML页面的端点。 端点 - /get_token 详情 - HTML页面只有一行代码,即{{ csrf_token}}。在Postman中请求该URL。您将在响应中看到令牌。
对于新的POST方法端点,添加名为X-CSRFToken的头,并将值设置为csrf_token。根据要求发送JSON数据。 enter image description here enter image description here

0

您可以在 JSON 数据中使用 csrfmiddlewaretoken: csrf_token,其中 csrf_token 是有效的令牌。但是,在无法提供正确令牌的情况下,您可以将 SessionAuthentication 注释或删除。

'DEFAULT_AUTHENTICATION_CLASSES': [
    'rest_framework.authentication.TokenAuthentication',
    # 'rest_framework.authentication.SessionAuthentication',
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接