Search code examples
djangodjango-rest-frameworkdjango-viewsdjango-authentication

Custom authorization in Django Rest


I am just a newbie with Django, python. I try to build 1 simple API Collection include CRUD basic, and authentication, authorization.

I have 1 simple Views like:

@api_view(['GET'])
@permission_classes([IsUser])
def get_test(request : Request):
 return JsonResponse({"message": "success"}, status = status.HTTP_200_OK)

and IsUser is:

class IsUser(IsAuthenticated):
  def has_permission(self, request : Request, view):
    token = request.query_params.get('token')
    if token:
      role = jwt.decode(token.split(" ").__getitem__(1), key="secret_key",algorithms="HS256").get('role')
    if role == 'User':
        return True
    else:
        return False
  return False

My purpose wants to parse the JWT token and authorization based on that. I wonder don't know if my way is really correct? Can anyone give me some comments as well as documentation to better understand this issue? I don't use any other lib because I want to code by myself at first to understand the flow.

Thanks for helping me.


Solution

  • If you are using the default JWT authentication of DRF then permission class IsAuthenticated will verify the the token for you and instead of specifying token in query parameter specify in headers.

    However, if you want to allow a specific type(role) of user to access your endpoint. Then create a subclass of BasePermission class as show in the example.

    Then simply add IsAuthenticated in @permission_classes([IsUser & IsAuthenticated]) to make it work.

    Again, this would work only if you are using the default Group model.

    Here is how you can import it from django.contrib.auth.models import Group

    from rest_framework.permissions import BasePermission
    
    USER = 'USER'
    
    class IsUser(BasePermission):
    
        def has_permission(self, request, view, user=None):
            if not user:
                user = request.user
            return USER in [role.name for role in user.groups.filter()]