每个特定方法的 Django OAuthToolkit 范围
Django OAuthToolkit Scopes per specific method
我正在使用 Django Rest Framework 和 OAuthTookit。
我希望令牌提供的范围应该是特定于 HTTP 方法的。例如:- 同一个 APIView 的 GET、PUT、DELETE 应该有不同的范围。
以下是我的 API。
class MyView(RetrieveUpdateDestroyAPIView):
permission_classes = [TokenHasScope]
required_scopes = ['scope1']
serializer_class = ModelSerializer
queryset = Model.objects.all()
目前,范围设置在class级别,这意味着访问所有的GET、PUT和DELETE方法,令牌应该有scope1
。
我希望不同的 HTTP 方法应该有不同的范围。如何为不同的方法设置不同的范围?
要处理这种情况,我认为您需要实施新权限 class,如下所示:
class TokenHasScopeForMethod(TokenHasScope):
def has_permission(self, request, view):
token = request.auth
if not token:
return False
if hasattr(token, "scope"):
# Get the scopes required for the current method from the view
required_scopes = view.required_scopes_per_method[request.method]
return token.is_valid(required_scopes)
然后像这样在您的视图中使用它:
class MyView(RetrieveUpdateDestroyAPIView):
permission_classes = [TokenHasScopeForMethod]
required_scopes_per_method = {'POST': ['post_scope'], 'GET': ['get_scope']}
serializer_class = ModelSerializer
queryset = Model.objects.all()
也许你可以使用TokenMatchesOASRequirements
权限class
class SongView(views.APIView):
authentication_classes = [OAuth2Authentication]
permission_classes = [TokenMatchesOASRequirements]
required_alternate_scopes = {
"GET": [["read"]],
"POST": [["create"], ["post", "widget"]],
"PUT": [["update"], ["put", "widget"]],
"DELETE": [["delete"], ["scope2", "scope3"]],
}
我喜欢@clément-denoix 的回答,但会稍微调整一下。
与其重新加载 TokenHasScope.has_permission
我建议重新定义
TokenHasScope.get_scopes
因为它是一种更小的方法,非常适合您的需要。原始 has_permission
方法还有我更愿意保留的附加逻辑。
像这样应该可以解决问题:
from django.core.exceptions import ImproperlyConfigured
from oauth2_provider.contrib.rest_framework import TokenHasScope
class TokenHasScopeForMethod(TokenHasScope):
def get_scopes(self, request, view):
try:
scopes = getattr(view, "required_scopes_per_method")
return scopes[request.method]
except (AttributeError, KeyError):
raise ImproperlyConfigured(
"TokenHasScope requires the view to define the required_scopes_per_method attribute"
)
我正在使用 Django Rest Framework 和 OAuthTookit。
我希望令牌提供的范围应该是特定于 HTTP 方法的。例如:- 同一个 APIView 的 GET、PUT、DELETE 应该有不同的范围。
以下是我的 API。
class MyView(RetrieveUpdateDestroyAPIView):
permission_classes = [TokenHasScope]
required_scopes = ['scope1']
serializer_class = ModelSerializer
queryset = Model.objects.all()
目前,范围设置在class级别,这意味着访问所有的GET、PUT和DELETE方法,令牌应该有scope1
。
我希望不同的 HTTP 方法应该有不同的范围。如何为不同的方法设置不同的范围?
要处理这种情况,我认为您需要实施新权限 class,如下所示:
class TokenHasScopeForMethod(TokenHasScope):
def has_permission(self, request, view):
token = request.auth
if not token:
return False
if hasattr(token, "scope"):
# Get the scopes required for the current method from the view
required_scopes = view.required_scopes_per_method[request.method]
return token.is_valid(required_scopes)
然后像这样在您的视图中使用它:
class MyView(RetrieveUpdateDestroyAPIView):
permission_classes = [TokenHasScopeForMethod]
required_scopes_per_method = {'POST': ['post_scope'], 'GET': ['get_scope']}
serializer_class = ModelSerializer
queryset = Model.objects.all()
也许你可以使用TokenMatchesOASRequirements
权限class
class SongView(views.APIView):
authentication_classes = [OAuth2Authentication]
permission_classes = [TokenMatchesOASRequirements]
required_alternate_scopes = {
"GET": [["read"]],
"POST": [["create"], ["post", "widget"]],
"PUT": [["update"], ["put", "widget"]],
"DELETE": [["delete"], ["scope2", "scope3"]],
}
我喜欢@clément-denoix 的回答,但会稍微调整一下。
与其重新加载 TokenHasScope.has_permission
我建议重新定义
TokenHasScope.get_scopes
因为它是一种更小的方法,非常适合您的需要。原始 has_permission
方法还有我更愿意保留的附加逻辑。
像这样应该可以解决问题:
from django.core.exceptions import ImproperlyConfigured
from oauth2_provider.contrib.rest_framework import TokenHasScope
class TokenHasScopeForMethod(TokenHasScope):
def get_scopes(self, request, view):
try:
scopes = getattr(view, "required_scopes_per_method")
return scopes[request.method]
except (AttributeError, KeyError):
raise ImproperlyConfigured(
"TokenHasScope requires the view to define the required_scopes_per_method attribute"
)