I have created simple permission class to protect my view.
class StaffOnly(permissions.BasePermission):
def has_permission(self, request, view):
token = request.META.get('HTTP_TOKEN', False) # Always returns False
user = CustomUser.objects.filter(token=token) # Which means no user found
if user.exists(): # This line won`t execute
user = user.get(token=token)
return user.role > 0
else:
raise PermissionDenied('No token')
View itself:
@api_view(["GET"])
@permission_classes([StaffOnly])
def book_list(request):
book_list = InfoBook.objects.all()
serializer_list = InfoBookSerializer(book_list, many=True)
return Response(data=serializer_list.data, status=status.HTTP_200_OK)
Then I was trying to send request from the client side.
// This is the part of React`s Component`s code. I`m sure that I`m not sending blank token and url is correct
fetch(HTTP + DOMAIN + API + VERSION + GETBOOKS, {
headers: {
"Token" : props.token
}
})
.then(res=>res.json())
.then(data => setBooks(data))
Unfortunatelly my permission class always denies access because of no token provided. As you can see, Im sending propriate header and I still can`
t get access to it for some reason.
Because Im sort of newbie I don``t
t know the reason why it is happening.
I``` ve figured out that I can` ``t get access to my token-header in permission class but I can access it inside of view.
# Client`s side request is the same
@api_view(["GET"])
# @permission_classes([StaffOnly]) # disable security from view
def book_list(request):
token = request.META.get('HTTP_TOKEN', False) # access token manually
print(token) # terminal output is Xg3Fk9DZkpInRvaOipS6UZg9D0x90xV...
book_list = InfoBook.objects.all()
serializer_list = InfoBookSerializer(book_list, many=True)
return Response(data=serializer_list.data, status=status.HTTP_200_OK)
I just wanted to create security permission class that will check certain header named "Token" and give or deny the permission. I`ve faced the problem where this class simply cant get access to this header which in view itself easily accessable.
After being messing with this problems for hours I finally figured out the solution!
The problem is that there is not just GET request being sent to my "book_list" view but also OPTIONS one. OPTION request is sort of setup thing which always goes before actual request. And it contains NO INFO ABOUT HEADERS DATA, ONLY HEADERS
NAMES.
With that being said the actual solution will look like this:
class StaffOnly(permissions.BasePermission):
def has_permission(self, request, view):
if request.method == "OPTIONS":
return True #always return true if this is the option request
#in other case start checking permissions
token = request.META.get('HTTP_TOKEN', False)
user = CustomUser.objects.filter(token=token)
if user.exists():
user = user.get(token=token)
return user.role > 0
else:
return False