我正在使用 django-oneall允许在我的网站上进行社交登录 session 身份验证。虽然它不是 django-rest-framework 的建议身份验证提供程序之一,但 rest_framework.authentication.SessionAuthentication
使用 django 的默认 session 身份验证。所以我认为集成应该相当简单。
在权限方面,最终我将使用 IsAdmin
,但出于开发目的,我只是将其设置为 IsAuthenticated
.当返回 403 时,我将权限放宽到 AllowAny
,但仍然没有骰子。这是我的休息框架配置:
设置.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',
),
}
编辑:我根据下面的答案得到了这个工作。原来
rest_framework
期望 csrftoken
cookie 和一个 X-CSRFToken
相同值的 header ,我设置我的前端代码为所有 ajax 请求发送该 header ,一切正常。
最佳答案
Django REST Framework 返回状态码 403
在几个相关情况下:
DEFAULT_PERMISSION_CLASSES
为 ('rest_framework.permissions.IsAuthenticated',)
时,以未经身份验证的用户身份发出 API 请求。rest_framework.authentication.SessionAuthentication
并且您没有在请求集中包含您的 CSRFToken。 我将针对测试 API 发出一些演示请求,以给出每个示例,以帮助您诊断您遇到的问题并展示如何解决它。我将使用
requests
图书馆。测试 API
我用一个模型设置了一个非常简单的 DRF API,
Life
,它包含一个字段( answer
,默认值为 42
)。从现在开始的一切都非常简单。我设置了ModelSerializer
- LifeSerializer
, 一个 ModelViewSet
- LifeViewSet
, 和 DefaultRouter
在 /life
网址路由。我已将 DRF 配置为要求用户经过身份验证才能使用 API 并使用 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
关于尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32653518/