I have this code of 2 views in Django. You will notice that each REST API call has a verify_login() function call that ensures that the request contains a verified JWT token. I’m wondering if there’s a better way to implement this so that I don’t have to have these lines specifically in every REST endpoint
verify_response = verify_login(request) if verify_response not None: return verify_response
I’m trying to follow the D.R.Y. (Do Not Repeat Yourself) principle of coding. It’d be nice if there was a cleaner way to represent this. I thought about maybe creating a module extending APIView that automatically has this and then all my Views extend that, but runs into the issue of having to call super().API_REQUEST() and then having to do the same if-statement check to see if it’s None or not.
class PostView(APIView): """ View for Post object * requires token authentication """ # Create post @swagger_auto_schema( request_body=PostSerializer, operation_description="Create a post object" ) def post(self, request): verify_response = verify_login(request) if verify_response not None: return verify_response serializer = PostSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # get all posts @swagger_auto_schema( operation_description="Get all posts from the DB" ) def get(self, request): verify_response = verify_login(request) if verify_response not None: return verify_response posts = Post.objects.all() serializer = PostSerializer(posts, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
Advertisement
Answer
You can use authentication classes alongside permission classes. If you want the authentication check to happen for all the APIs of your application, put your classes in settings.REST_FRAMEWORK. If you want it for specific APIView’s, put them in permission_classes & authentication_classes class variables. Check out the doc for more details.
Example,
class JWTAuthenticataion(BaseAuthentication): def authenticate(self, request): ... # write your JWT implementation here # settings.py: REST_FRAMEWORK = { ... "DEFAULT_AUTHENTICATION_CLASSES": ( "path.to.JWTAuthentication", ), "DEFAULT_PERMISSION_CLASSES": ( "rest_framework.permissions.IsAuthenticated", ) } # or # api.py class YourAPIView(APIView): permission_classes = (IsAuthenticated, ) authentication_classes = (JWTAuthentication, ) ...