从postman运行django api:CSRF验证失败

时间:2017-10-25 07:16:14

标签: python django curl

我试图使用postman运行api。我的应用程序是使用django 1.11.6python 3.5中开发的。

我的应用已安装在ubuntu服务器上。我没有登录机制来创建csrf令牌。

这些是我遵循的步骤:

  1. 点击"导入"左上角的标签。
  2. 选择原始文本选项并粘贴我的cURL命令。
  3. 点击导入,我在Postman构建器中有命令
  4. 按发送按钮。
  5. 我的curl命令是:

    curl -i -H 'Accept: application/json; indent=4' -X POST  https://127.0.0.1/users/:register/ -d "id=111&firstname=zinonas&yearofbirth=2007&lastname=Antoniou&othernames="
    

    我得到的错误是Forbidden (403) - CSRF verification failed. Request aborted

    当我通过curl command运行cygwin时,它正常运行。

    这是我正在使用的视图功能:

    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}
            return Response(resp, status=resp_status)
    

    settings.py我有:

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        ),
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.SessionAuthentication',
            'rest_framework.authentication.TokenAuthentication',
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        )
    }
    

5 个答案:

答案 0 :(得分:1)

要发出AJAX请求,您需要在HTTP标头中包含CSRF令牌,如described in the Django documentation

第一个选项

enter image description here

第二个选项 enter image description here

答案 1 :(得分:0)

将您的课程更新为此

from braces.views import CsrfExemptMixin
class your_class(CsrfExemptMixin, ......yours_here)
   def post(...):
       [....]

这将告诉django允许没有csrf的请求

答案 2 :(得分:0)

试试这个。

from django.views.decorators.csrf import csrf_exempt
class ApiUserRegister(APIView):
permission_classes = ()
serializer_class = RegisterUserSerializer

    @csrf_exempt
    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)

答案 3 :(得分:0)

在urls文件中,尝试以下操作:

urlpatterns = [
    url(r'^your_uri/', views.YourView.as_view()),
]

这将告诉django允许没有csrf的请求

答案 4 :(得分:0)

Django在登录时设置csrftoken cookie。登录后,我们可以从Postman中的cookie中看到csrf令牌。 (见图片) CSRFtoken from cookies

我们可以获取此令牌并将其手动设置在标题中。 但是,此令牌到期时必须手动更改。在到期的基础上进行此过程变得很乏味。

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

var xsrfCookie = postman.getResponseCookie("csrftoken"); postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);

这将提取csrf令牌并将其设置为当前环境中名为csrftoken的环境变量。 现在在我们的请求中,我们可以使用此变量设置标头。(参见图片) Set {{csrftoken}} in your header

当令牌过期时,我们只需要再次登录即可,而csrf令牌会自动更新。

感谢@chillaranand from hackernoon.com撰写原始帖子