当我尝试作为客户端请求时,DRF 以 403 错误响应我 [客户端凭据授权]

Ham*_*adi 2 python django oauth-2.0 django-rest-framework

settings.py文件中我写了这个设置:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}
Run Code Online (Sandbox Code Playgroud)

当我使用password grant应用程序中的令牌调用任何 API 时,它工作正常,但是当我尝试使用client credential grant应用程序中的令牌调用相同的 API 时,它不起作用并且它响应 403 错误:

{ "detail": "You do not have permission to perform this action." }. 
Run Code Online (Sandbox Code Playgroud)

是因为默认权限吗?我不知道我必须使用什么权限来代替!?

Ham*_*adi 5

终于解决了!问题是permission我正在使用。实际上,IsAuthenticated权限检查request.userNone在您使用client credentials授权时进行的。由于在 DRF 中没有permission支持clien credentials授权,您必须使用您自己的DRF 自定义权限。这是我需要和使用的:

from rest_framework.permissions import BasePermission
class IsAuthenticatedOrClientCredentialPermission(BasePermission):
    def has_permission(self, request, view):
        if request.auth is None:
            return False
        grant_type = request.auth.application.get_authorization_grant_type_display()
        if request.user is None:
            if grant_type == 'Client credentials':
                request.user = request.auth.application.user  # <-- this is because I needed to get the user either the grant is 'password' or 'client credentials'
                return True
            else:
                return False
        else:
            return True
Run Code Online (Sandbox Code Playgroud)

但是您可能只想获得一个权限来检查授权类型是否为client credentials并授予权限,如果是,这就是您所需要的:

from rest_framework.permissions import BasePermission
class ClientCredentialPermission(BasePermission):
    def has_permission(self, request, view):
        if request.auth is None:
            return False
        grant_type = request.auth.application.get_authorization_grant_type_display()
        if request.user is None and grant_type == 'Client credentials':
            return True
        else:
            return False
Run Code Online (Sandbox Code Playgroud)

注意:如果您想使用第二个自定义权限,请注意request.userisNone并且您可以通过request.auth.application.user.

使用(自定义)权限:

您可以通过将它们添加到适当的视图来使用您的自定义权限。(就像在 下使用任何 DRF 权限一样rest_framework.permissions

基于类的视图:

class ExampleView(APIView):
    permission_classes = [ClientCredentialPermission]  # <-- Add your permissions to this list

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)
Run Code Online (Sandbox Code Playgroud)

基于函数的视图:

@api_view(['GET'])
@permission_classes([ClientCredentialPermission])  # <-- Add your permissions to this list
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)
Run Code Online (Sandbox Code Playgroud)