问题
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