移除特定 URL 路径的身份验证和权限控制。

7

我正在使用DRF,并遇到了这个问题。我有一个第三方视图,我在urls.py文件中像这样导入:

from some_package import some_view

urlpatterns = [
    path('view/',some_view)
]

但我面临的问题是,由于我在settings.py中启用了默认权限类,就像这样:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
               'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES':(
                'rest_framework.permissions.IsAuthenticated',
    ),

}

现在当我使用URL调用该视图时,它会显示身份验证错误,因为我没有提供令牌。有没有一种方法可以绕过身份验证错误,而不必直接更改视图?我知道我们可以删除该特定视图的权限,但这将需要对some_view函数代码进行更改。但是我不想这样做,假设我们无法访问该函数,我们只能传递数据并接收响应。如何在不更改该函数代码的情况下绕过身份验证。

我尝试搜索但找不到我要找的内容。

我认为可能有一种方式可以通过urls.py实现这一点,例如指定任何参数或类似的东西,使该特定视图绕过身份验证而不必更改函数代码。

类似于以下内容:

from some_package import some_view

    urlpatterns = [
        path('view/',some_view,"some_parameter") #passing someparameter from here or something like that
    ]

我正在寻找的是否可能?谢谢提前!


我不知道有任何方法可以做到这一点。你最好的选择是包装视图(即编写自己的视图)并设置authentication_classes。这对你有用吗? - yvesonline
1
你也可以移除 DEFAULT_AUTHENTICATION_CLASSESDEFAULT_PERMISSION_CLASSES,并将其放入自己的父类中进行身份验证和授权,然后在视图中继承该类。这样,你的第三方视图就不会默认使用 settings.py 中提供的内容,因为你没有提供任何内容。 - yvesonline
是的,我可以做到,但这将导致进行更多的更改。与其按照您建议的方式进行操作,不如覆盖该函数并为覆盖函数指定“authentication_classes”,然后从覆盖函数中调用原始函数。@yvesonline - Shubham Devgan
这就是我在第一条评论中所说的意思。老实说,如果你只是导入一个视图,我认为这是可行的方法。 - yvesonline
我已经尝试过这种覆盖的方式。对我来说效果很好。这是一个不错的做法。我很久以前就这样做了。 - Razia Khan
3个回答

6

因此,对于第三方视图来说,最合适的方法是通过在urls.py中定义装饰器来使用它们:

示例一

我假设some_view是从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())
]

案例 2

我假设 some_view 是一个简单的 Django 视图函数,并且您需要为 GET 方法定义它:

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))))
]

案例3

我假设some_view是一个被api_view修饰的DRF视图函数。这是最难甚至可能是最不可能的部分,因为你必须取消之前的api_view装饰器。如果视图函数已经被api_view修饰,那么它已经被转换为Django视图函数,所以既不能添加permision_classes也不能添加authentication_classes到类中:


0

您可以覆盖默认的身份验证类以跳过特定 URL 的身份验证。

例如:

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)

你需要创建一个 PUBLIC_URLS 列表,用于绕过身份验证。

现在在 rest 框架设置中使用这个类作为 DEFAULT_PERMISSION_CLASSES。并删除默认的 IsAuthenticated 类。

虽然我推荐使用装饰器方法。 查看文档:https://www.django-rest-framework.org/api-guide/permissions/#allowany

装饰器方法更加冗长,通过查看函数可以判断它是否是公共的。


0

@Bedilbek的回答对我很有用,但如果您更喜欢在视图内使用不同的语法并定义permission_classesauthentication_classes而不是在urls.py中,您可以采取以下措施:

from rest_framework import permissions
from rest_framework.views import APIView

class SomeView(APIView):
    permission_classes = [permissions.AllowAny]
    authentication_classes = []

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接