Python Django rest api:邮递员可以';看不到CSRF令牌

Python Django rest api:邮递员可以';看不到CSRF令牌,python,django,curl,django-rest-framework,postman,Python,Django,Curl,Django Rest Framework,Postman,我在ubuntu服务器上使用django 1.11.6和python 3.5 我有一个用于用户注册的api 这是我的curl命令: curl -i -H 'Accept: application/json; indent=4' -X POST https://mydomain/users/:register/ -d "id=222111&firstname=andy&yearofbirth=2007&lastname=Chris&othernames="

我在
ubuntu
服务器上使用
django 1.11.6
python 3.5

我有一个用于用户注册的api

这是我的
curl
命令:

curl -i -H 'Accept: application/json; indent=4'  -X POST  https://mydomain/users/:register/ -d "id=222111&firstname=andy&yearofbirth=2007&lastname=Chris&othernames=" 
当我在
cygwin
中使用它时,我得到了期望的响应:

HTTP/1.1 200 OK
Date: Thu, 26 Oct 2017 06:41:00 GMT
Server: Apache/2.4.18 (Ubuntu)
Allow: POST, OPTIONS
Vary: Accept,Cookie
Content-Length: 188
X-CSRFToken: acY2oPGkkqkzBe9itBq56oFeTFAllqv2bS39c7TpPN9LlGh90E1FxsI0YXLlu1Vu
X-Frame-Options: SAMEORIGIN
Set-Cookie:  csrftoken=QfxnUGTmrRi1MThcn8Qau5ytnt2NR8tdRVCuIY6rWe7dwlp3UbrKV9BfsLdN0JTF; expires=Thu, 25-Oct-2018 06:41:01 GMT; Max-Age=31449600; Path=/
Content-Type: application/json

{
    "isnew": "true",
    "user": {
        "othernames": "",
        "id": "222111",
        "firstname": "Andy",
        "yearofbirth": 2007,
        "lastnames": "Chris"
    }
}
如我所见,我有
X-CSRFToken
头和'CSRFToken'cookie

当我尝试从
postman
运行相同的
curl
命令时,我得到:

Forbidden (403)
CSRF verification failed. Request aborted.
You are seeing this message because this HTTPS site requires a 'Referer header' to be sent by your Web browser, but none was sent. This header is required for security reasons, to ensure that your browser is not being hijacked by third parties.
If you have configured your browser to disable 'Referer' headers, please re-enable them, at least for this site, or for HTTPS connections, or for 'same-origin' requests.
我在
views.py中的功能是:

class ApiUserRegister(APIView):
    permission_classes = ()
    serializer_class = RegisterUserSerializer

    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)
        # Check format and unique constraint
        serializer.is_valid(raise_exception=True)
        data = serializer.data

        if User.objects.filter(id=data['id']).exists():
            user = User.objects.get(id=data['id'])
            is_new = "false"
            resp_status = status.HTTP_200_OK
        else:
            user = User.objects.create(id=data['id'],
                                       firstname=data['firstname'],
                                       yearofbirth=data['yearofbirth'],
                                       lastname=data['lastname'],
                                       othernames=data['othernames'])
            user.save()
            is_new = "true"
            resp_status = status.HTTP_201_CREATED
        resp = {"user": serializer.get_serialized(user),
                "isnew": is_new} #csrfmiddlewaretoken: csrf_token
        return Response( resp, status=resp_status, headers = {"X-CSRFToken":get_token(request)})

您可以创建一个额外的视图来生成CSRF令牌,您可以首先通过GET请求收集这些令牌

示例

# views.py

from django.middleware.csrf import get_token

class CSRFGeneratorView(APIView):
    def get(self, request):
        csrf_token = get_token(request)
        return Response(csrf_token)

# urls.py

urlpatterns += [url(r'generate_csrf/$', views.CSRFGeneratorView.as_view())]
curl -X POST -d "csrfmiddlewaretoken=<token_value>" <url>
然后,您可以首先调用此视图以获得CSRF令牌,以便在进一步的请求中使用

编辑:获取令牌后,您将把它添加到表单数据中

示例

# views.py

from django.middleware.csrf import get_token

class CSRFGeneratorView(APIView):
    def get(self, request):
        csrf_token = get_token(request)
        return Response(csrf_token)

# urls.py

urlpatterns += [url(r'generate_csrf/$', views.CSRFGeneratorView.as_view())]
curl -X POST -d "csrfmiddlewaretoken=<token_value>" <url>
curl-X POST-d“csrfmiddlewaretoken=”

Ref:

您可以创建一个附加视图来生成CSRF令牌,您可以首先通过GET请求收集该令牌

示例

# views.py

from django.middleware.csrf import get_token

class CSRFGeneratorView(APIView):
    def get(self, request):
        csrf_token = get_token(request)
        return Response(csrf_token)

# urls.py

urlpatterns += [url(r'generate_csrf/$', views.CSRFGeneratorView.as_view())]
curl -X POST -d "csrfmiddlewaretoken=<token_value>" <url>
然后,您可以首先调用此视图以获得CSRF令牌,以便在进一步的请求中使用

编辑:获取令牌后,您将把它添加到表单数据中

示例

# views.py

from django.middleware.csrf import get_token

class CSRFGeneratorView(APIView):
    def get(self, request):
        csrf_token = get_token(request)
        return Response(csrf_token)

# urls.py

urlpatterns += [url(r'generate_csrf/$', views.CSRFGeneratorView.as_view())]
curl -X POST -d "csrfmiddlewaretoken=<token_value>" <url>
curl-X POST-d“csrfmiddlewaretoken=”
参考:

很高兴知道 Django在登录时设置csrftoken cookie。登录后,我们可以在邮递员的cookies中看到csrf令牌。(见图)


第一种方法


我们可以抓取这个令牌并手动在头中设置它。 但该令牌在到期时必须手动更改。在过期的基础上执行此过程会变得单调乏味


更好的方法


相反,我们可以使用Postman脚本功能从cookie中提取令牌,并将其设置为环境变量。在邮递员的测试部分,添加以下行

var xsrfCookie = postman.getResponseCookie("csrftoken"); postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);
这将提取csrf令牌并将其设置为当前环境中名为csrftoken的环境变量。 现在,在我们的请求中,我们可以使用这个变量来设置头

当令牌过期时,我们只需再次登录,csrf令牌就会自动更新

感谢您的原创帖子

很好地了解 Django在登录时设置csrftoken cookie。登录后,我们可以在邮递员的cookies中看到csrf令牌。(见图)


第一种方法


我们可以抓取这个令牌并手动在头中设置它。 但该令牌在到期时必须手动更改。在过期的基础上执行此过程会变得单调乏味


更好的方法


相反,我们可以使用Postman脚本功能从cookie中提取令牌,并将其设置为环境变量。在邮递员的测试部分,添加以下行

var xsrfCookie = postman.getResponseCookie("csrftoken"); postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);
这将提取csrf令牌并将其设置为当前环境中名为csrftoken的环境变量。 现在,在我们的请求中,我们可以使用这个变量来设置头

当令牌过期时,我们只需再次登录,csrf令牌就会自动更新


感谢for original post

这是您在启用CSRF验证后得到的预期错误。您需要禁用CSRF验证或使用Django创建CSRF令牌,并在请求中使用这些令牌。@SachinKukreja我昨天尝试禁用它,但没有成功。你能给我一个如何用Django创建CSRF令牌并在请求中使用这些令牌的例子吗?请看这里我昨天的问题:这是您在启用CSRF验证后得到的预期错误。您需要禁用CSRF验证或使用Django创建CSRF令牌,并在请求中使用这些令牌。@SachinKukreja我昨天尝试禁用它,但没有成功。你能给我一个如何用Django创建CSRF令牌并在请求中使用这些令牌的例子吗?请看这里我昨天的问题:我试图使用它,但我收到消息:
“详细信息”:“未提供身份验证凭据。”
我在设置py中禁用了
'rest\u framework.permissions.IsAuthenticated'
'rest\u framework.Authentication.TokenAuthentication'
,现在我得到了它。如何将其添加到我的视图中?如果您将其用于Postman/cURL的测试目的,那么您可以为未经身份验证的用户打开此视图,否则,您必须告诉我您如何进行身份验证。编辑了答案。我尝试了您的建议答案,但
禁止403
仍保留在
邮递员
中。我尝试使用它,但收到消息:
“详细信息”:“未提供身份验证凭据。”
I在设置py中禁用了
'rest\u framework.permissions.IsAuthenticated'
'rest\u framework.authentication.TokenAuthentication'
,现在我得到了它。如何将其添加到我的视图中?如果您将其用于Postman/cURL的测试目的,那么您可以为未经身份验证的用户打开此视图,否则您必须告诉我如何进行身份验证。编辑了答案。我尝试了您的建议答案,但
禁用403
仍保留在
Postman
中。