尽管允许AllowAny权限,django-rest-framework在POST,PUT,DELETE上返回403响应

cko*_*kot 12 authentication django permissions django-rest-framework

我正在使用django-oneall来允许我的网站上的社交登录会话身份验证.虽然它不是django-rest-framework的建议auth提供程序之一,但 rest_framework.authentication.SessionAuthentication使用django的默认会话身份验证.所以我认为整合应该相当简单.

在权限方面,最终我将使用IsAdmin,但出于开发目的,我只是将它设置为IsAuthenticated.当返回403s时,我放宽了权限AllowAny,但仍然没有骰子.这是我的休息框架配置:

settings.py

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',
    ),
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我根据下面的答案得到了这个工作.事实证明,rest_framework期望csrftokencookie和aa X-CSRFToken具有相同的值,我设置我的前端代码为所有ajax请求发送该标头,一切正常.

chu*_*ash 29

Django REST Framework 403在几个相关情况下返回状态代码:

  • 当您没有所需的权限级别时(例如,在未经许可的情况下将API请求作为未经身份验证的用户DEFAULT_PERMISSION_CLASSES)('rest_framework.permissions.IsAuthenticated',).
  • 当您执行不安全的请求类型(POST,PUT,PATCH或DELETE - 一个应该有副作用的请求)时,您正在使用rest_framework.authentication.SessionAuthentication并且您没有将CSRFToken包含在requeset中.
  • 当您执行不安全的请求类型时,您所包含的CSRFToken不再有效.

我将针对测试API发出一些演示请求,以提供每个示例,以帮助您诊断您遇到的问题并演示如何解决它.我将使用该requests库.

测试API

我使用单个模型设置了一个非常简单的DRF API Life,它包含一个字段(answer默认值为42).从现在开始,一切都很直接; 我在URL路由上设置了ModelSerializer- LifeSerializer,a ModelViewSet- LifeViewSet和a .我已配置DRF以要求用户进行身份验证以使用API​​并使用.DefaultRouter/lifeSessionAuthentication

点击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
Run Code Online (Sandbox Code Playgroud)