Django的休息框架返回上POST 403响应,PUT,DELETE尽管AllowAny权限 [英] django-rest-framework returning 403 response on POST, PUT, DELETE despite AllowAny permissions

查看:2133
本文介绍了Django的休息框架返回上POST 403响应,PUT,DELETE尽管AllowAny权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Django的oneall 来让我的网站上社会登录会话的认证。虽然它不是Django的休息框架建议的权威性供应商之一, rest_framework.authentication.SessionAuthentication 使用Django默认的会话验证。所以我想它应该是相当简单的集成。

I'm using a django-oneall to allow social login session authentication on my site. While it isn't one of the suggested auth providers for django-rest-framework, rest_framework.authentication.SessionAuthentication uses django's default session authentication. so I thought it should be fairly simple to integrate.

在权限方面,最终我将使用 IsAdmin ,但为发展宗旨,我不得不将其设置为 IsAuthenticated 。当返回403s,我放松了权限 AllowAny ,但仍然没有骰子。这里是我的休息框架的配置:

On the permissions side, ultimately I'll use IsAdmin, but for development purposes, I just had it set to IsAuthenticated. When that returning 403s, I relaxed the permissions to AllowAny, but still no dice. Here's my rest framework config:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
        # 'rest_framework.permissions.IsAuthenticated',
        # 'rest_framework.permissions.IsAdminUser',
     ),
    'PAGE_SIZE': 100,
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework.filters.DjangoFilterBackend',
    ),
}

编辑:

我基于下面的回答这个工作。事实证明, rest_framework 预计两个 csrftoken 饼干和AA X-CSRFToken 相同值的头,我安装我的前端code来发送标题为所有Ajax请求,一切工作正常。

I got this working based on the answer below. It turns out that rest_framework expects both the csrftoken cookie and a a X-CSRFToken Header of the same value, I setup my front-end code to send that header for all ajax requests and everything worked fine.

推荐答案

Django的REST框架返回状态code 403 下的一对夫妇的相关情况:

Django REST Framework returns status code 403 under a couple of relevant circumstances:


  • 当你不具备所需的权限级别(例如作出API请求作为未认证的用户时, DEFAULT_PERMISSION_CLASSES ('rest_framework.permissions .IsAuthenticated')

  • 当你做一个不安全的请求类型(POST,PUT,贴片或DELETE - 应该有副作用的请求),您使用的是 rest_framework.authentication.SessionAuthentication 和你不包括在requeset你CSRFToken。

  • 当你在做你已经包含不安全的请求类型和CSRFToken不再有效。

  • When you don't have the required permission level (e.g. making an API request as an unauthenticated user when DEFAULT_PERMISSION_CLASSES is ('rest_framework.permissions.IsAuthenticated',).
  • When you doing an unsafe request type (POST, PUT, PATCH or DELETE - a request that should have side effects), you are using rest_framework.authentication.SessionAuthentication and you've not included your CSRFToken in the requeset.
  • When you are doing an unsafe request type and the CSRFToken you've included is no longer valid.

我要做出对测试API几个演示请求给每个示例,以帮助您诊断其发出你有,并展示如何解决它。我将使用要求库。

I'm going to make a few demo requests against a test API to give an example of each to help you diagnose which issue you are having and show how to resolve it. I'll be using the requests library.

测试API

我建立了一个非常简单的DRF API与单一的模式,人寿,只包含一个字段(答案 42 )。一切从这里开始了为pretty向前伸直;我设置了一个 ModelSerializer - LifeSerializer ,一个 ModelViewSet - LifeViewSet defaultrouter中 /生活 URL路径。我已经配置DRF,要求用户进行身份验证使用API​​,并使用 SessionAuthentication

I set up a very simple DRF API with a single model, Life, that contains a single field (answer, with a default value of 42). Everything from here on out is pretty straight forward; I set up a ModelSerializer - LifeSerializer, a ModelViewSet - LifeViewSet, and a DefaultRouter on the /life URL route. I've configured DRF to require user's be authenticated to use the API and to use SessionAuthentication.

击中API

import json
import requests

response = requests.get('http://localhost:8000/life/1/')
# prints (403, '{"detail":"Authentication credentials were not provided."}')
print response.status_code, response.content

my_session_id = 'mph3eugf0gh5hyzc8glvrt79r2sd6xu6'
cookies = {}
cookies['sessionid'] = my_session_id
response = requests.get('http://localhost:8000/life/1/',
                        cookies=cookies)
# prints (200, '{"id":1,"answer":42}')
print response.status_code, response.content

data = json.dumps({'answer': 24})
headers = {'content-type': 'application/json'}
response = requests.put('http://localhost:8000/life/1/',
                        data=data, headers=headers,
                        cookies=cookies)
# prints (403, '{"detail":"CSRF Failed: CSRF cookie not set."}')
print response.status_code, response.content

# Let's grab a valid csrftoken
html_response = requests.get('http://localhost:8000/life/1/',
                             headers={'accept': 'text/html'},
                             cookies=cookies)
cookies['csrftoken'] = html_response.cookies['csrftoken']
response = requests.put('http://localhost:8000/life/1/',
                        data=data, headers=headers,
                        cookies=cookies)
# prints (403, '{"detail":"CSRF Failed: CSRF token missing or incorrect."}')
print response.status_code, response.content

headers['X-CSRFToken'] = cookies['csrftoken']
response = requests.put('http://localhost:8000/life/1/',
                        data=data, headers=headers,
                        cookies=cookies)
# prints (200, '{"id":1,"answer":24}')
print response.status_code, response.content

这篇关于Django的休息框架返回上POST 403响应,PUT,DELETE尽管AllowAny权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆