我正在尝试将使用Django REST 框架的 API 添加到使用Django OAuth2 工具包的现有代码库中。现有视图利用 OAuth2 工具包的后端修改 Djangologin_required
装饰器的行为,使其使用 OAuth2 身份验证这一事实。基于函数的视图看起来类似于教程示例中的视图:
from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponse
@login_required()
def secret_page(request, *args, **kwargs):
return HttpResponse('Secret contents!', status=200)
我正在尝试根据我的情况调整https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html上给出的示例,但我发现这不是一个精确的对应关系,因为该示例使用 DRF 的ModelViewSet
类,而我当前的视图使用(集成度较低的)基于通用类的视图:
from rest_framework import generics
from ..models import Session
from ..serializers import SessionSerializer
class SessionDetail(generics.UpdateAPIView):
queryset = Session.objects.all()
serializer_class = SessionSerializer
我将默认权限类设置为IsAuthenticated
in settings.py
:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
这应该允许Session
使用 PATCH 请求更新对象,但它似乎会返回与用 .403 Forbidden
装饰的当前视图类似的用例的响应login_required
。
如何更新SessionDetail
视图,使其行为与用 装饰的函数视图相同login_required
?我怀疑我需要使用TokenHasReadWriteScope权限类,因为这似乎是唯一required_scopes
可选的。(用装饰的视图login_required
也不提供required_scopes
)。
会不会是这样:
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from oauth2_provider.contrib.rest_framework import OAuth2Authentication, TokenHasReadWriteScope
from ..models import Session
from ..serializers import SessionSerializer
class SessionDetail(generics.UpdateAPIView):
authentication_classes = [OAuth2Authentication]
permission_classes = [TokenHasReadWriteScope]
queryset = Session.objects.all()
serializer_class = SessionSerializer
另外,我是否必须像这样更新我的REST_FRAMEWORK
设置DEFAULT_AUTHENTICATION_CLASSES
:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
)
}
现在,如果我运行服务器并尝试使用可浏览 API 发出补丁请求,我会收到401 Unauthorized
错误消息:
此外,如果我Log in
使用刚刚创建的用户名和密码python manage.py createsuperuser
,它会直接返回此401
页面,而不是像我期望的那样使用表单发出 PATCH 请求。
有想法该怎么解决这个吗?