问题
I'm working with DRF and came across this issue. I have a third-party view which I'm importing in my urls.py
file like this :
from some_package import some_view
urlpatterns = [
path('view/',some_view)
]
but the issue I'm facing is since I have enabled default permission classes in my settings.py
like this:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
}
now when I call that view using the url , it gives me authentication error as I'm not providing token .Is there a way I can bypass authentication error without having to make changes in view directly,I know that we can remove permission for that particular view , but for that I'll have to make changes to that some_view
function code. But I don't want to do that,let's say we don't have access to that function we can only pass data and receive response. How can I bypass authentication without having to change that functions code .
I tried searching but couldn't find what I'm looking for.
I was assuming that there might be someway we can do that from urls.py like specifying any parameter or something like that which make that particular view to bypass authentication without having to change functions code.
somthing like this :
from some_package import some_view
urlpatterns = [
path('view/',some_view,"some_parameter") #passing someparameter from here or something like that
]
Is it possible what I'm looking for ? Thanks in advance :)
回答1:
So, the most appropriate way for third-party views is to use decorators by defining them inside your urls.py
:
Case 1
I assume that some_view
is a class inherited from rest_framework.views.APIView
:
urls.py
from django.urls import path
from rest_framework.decorators import permission_classes, authentication_classes
from rest_framework.permissions import AllowAny
from some_package import some_view
urlpatterns = [
path('', authentication_classes([])(permission_classes([AllowAny])(some_view)).as_view())
]
Case 2
I assume that some_view
is a simple Django view function and you need to define it for GET
method:
urls.py
from django.urls import path
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny
from some_package import some_view
urlpatterns = [
path('', api_view(['GET'])(authentication_classes([])(permission_classes([AllowAny])(some_view))))
]
Case 3
I assume that some_view
is an api_view
decorated DRF view function. This is the hardest and most probably the most impossible part because you have to undecorate the previous api_view
decorator. If view function is decorated with api_view
, then it is already converted into Django view function so neither permision_classes
nor authentication_classes
can be appended to class:
回答2:
Didn't you try :
from rest_framework.permissions import AllowAny
from rest_framework.decorators import authentication_classes, permission_classes
@authentication_classes((AllowAny, ))
@permission_classes((AllowAny, ))
def method()
回答3:
You can override the default authentication class to skip auth for specific urls.
For example:
class CustomIsAuthenticated(IsAuthenticated):
def has_permission(self, request, view):
# make a list of public urls
if request.path in PUBLIC_URLS:
return True
return super().has_permission(request, view)
You have to create a list of PUBLIC_URLS
which bypass authentication.
Now use this class in the DEFAULT_PERMISSION_CLASSES
in rest framework settings. And remove the default IsAuthenticated
class.
Although I recommend the decorators approach. check docs: https://www.django-rest-framework.org/api-guide/permissions/#allowany
Decorators approach is more verbose and by looking at the function you can make out if it is public or not.
来源:https://stackoverflow.com/questions/60666418/remove-authentication-and-permission-for-specific-url-path