Django REST Framework Deep Dive - Where is it determined that an enpoint needs an auth token

烂漫一生 提交于 2021-02-10 18:41:43

问题


general django question for those who are more experienced than myself,

I'm reading through the code posted for a tutorial on thinkster.io:

https://github.com/howardderekl/conduit-django/tree/master/conduit/apps

There's an endpoint pertaining to the User model authenticion/models.py that requires an Authorization header for it to return user information defined here in authentication/views.py:

class UserRetrieveUpdateAPIView(RetrieveUpdateAPIView):
    permission_classes = (IsAuthenticated,)
    renderer_classes = (UserJSONRenderer,)
    serializer_class = UserSerializer

    def retrieve(self, request, *args, **kwargs):
        serializer = self.serializer_class(request.user)
        return Response(serializer.data, status=status.HTTP_200_OK)

My question is how/where is it (supposed to be) determined that an endpoint requires this Authorization. My thought is that it is tied to the permission_classes variable stated in the UserRetrieveUpdateAPIVIiew class above. I dug into the package location where this was imported from (from rest_framework.permissions import IsAuthenticated), but that doesn't appear to contain anything pertaining to an HTTP header:

class BasePermissionMetaclass(OperationHolderMixin, type):
    pass


class BasePermission(metaclass=BasePermissionMetaclass):
    """
    A base class from which all permission classes should inherit.
    """

    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
    """
    return True

    def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
    """
        return True

... ... ...

class IsAuthenticated(BasePermission):
    """
    Allows access only to authenticated users.
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

I'm looking for best practices on how to structure headers like this for HTTP methods in my backend. Any ideas on where I should look, somewhere in settings.py maybe?

Thanks!

Bonus question:

This header requires two strings in your request. First being 'Token', followed by a space, then the actual JWT for that user. Is this standard practice to use two strings like this? If so, what's the reasoning. I've seen this before with other seemingly arbitrary words used for the first string, 'Token'


回答1:


As shown in the documentation :

REST framework will attempt to authenticate with each class in the list, and will set request.user and request.auth using the return value of the first class that successfully authenticates.

So if you use a token authentication scheme, the header Authorization: Token ... will result in the setup of the request.user and request.user.is_autenticated will be set to true for the view.

By combining it with the IsAuthenticated permission class, the view will only be accessible if the authorization token is set (and if you don't allow other authentication schemes)

For your second question, you can indeed put any string you want. Here DRF uses Token to make it clearer for which authentication scheme it is used. Since a lot of apps also uses a "Token", a lot of them use the same word. You can also often find Bearer.




回答2:


Django REST Framework comes with a package for Token Authentication, which is probably what you are looking for:

https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication

With it, you can assign tokens to individual users, which they can use in lieu of a username and password to authenticate against endpoints. This token is provided in the HTTP header. As for your second question, by providing Token as a convention, it would allow for other custom authentication types:

https://www.django-rest-framework.org/api-guide/authentication/#custom-authentication

The permission_classes are what determine what, if any, authentication is necessary. Good luck!



来源:https://stackoverflow.com/questions/57517366/django-rest-framework-deep-dive-where-is-it-determined-that-an-enpoint-needs-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!