Django的休息框架返回上POST 403响应,PUT,DELETE尽管AllowAny权限 [英] django-rest-framework returning 403 response on POST, PUT, DELETE despite AllowAny permissions
问题描述
我使用的是 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屋!