【问题标题】:In Django REST framework's authentication, how do I set the default access scheme to allow all endpoints to not require authentication?在 Django REST framework 身份验证中,如何设置默认访问方案以允许所有端点不需要身份验证?
【发布时间】:2021-11-30 09:52:50
【问题描述】:

我正在使用 Django 3.2 和 djangorestframework==3.12.2。我最近将此添加到我的设置文件中,因为我想向我的应用程序添加一些安全端点...

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
         'rest_framework.permissions.IsAuthenticated',
         'rest_framework.permissions.IsAdminUser',
         ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    )
}

JWT_AUTH = {
    # how long the original token is valid for
    'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),

}

但是,这似乎导致我的所有端点都需要身份验证。例如,我在 views.py 文件中设置了这个视图

class CoopList(APIView):
    """
    List all coops, or create a new coop.
    """
    def get(self, request, format=None):
        contains = request.GET.get("contains", "")
        if contains:
            coops = Coop.objects.find(
                partial_name=contains,
                enabled=True
            )
        else:
            partial_name = request.GET.get("name", "")
            enabled_req_param = request.GET.get("enabled", None)
            enabled = enabled_req_param.lower() == "true" if enabled_req_param else None
            city = request.GET.get("city", None)
            zip = request.GET.get("zip", None)
            street = request.GET.get("street", None)
            state = request.GET.get("state", None)
            coop_types = request.GET.get("coop_type", None)
            types_arr = coop_types.split(",") if coop_types else None

            coops = Coop.objects.find(
                partial_name=partial_name,
                enabled=enabled,
                street=street,
                city=city,
                zip=zip,
                state_abbrev=state,
                types_arr=types_arr
            )
        serializer = CoopSearchSerializer(coops, many=True)
        return Response(serializer.data)

可在我的 urls.py 文件中使用

path('coops/', views.CoopList.as_view()),

但是现在当我尝试打电话时,我得到了以下响应

{"detail":"Authentication credentials were not provided."}

我只希望保护某些视图/端点。如何默认所有视图都可以访问,并且只指定一些视图/端点使用提供的 JWT 进行验证?

【问题讨论】:

    标签: python-3.x django-rest-framework django-views django-authentication django-contrib


    【解决方案1】:

    'DEFAULT_PERMISSION_CLASSES' 方便地应用于所有视图,除非手动覆盖。在您的情况下,两个列出的权限都需要对用户进行身份验证。仅供参考,该列表以OR 方式评估。

    如果你想默认允许所有人并且只收紧特定视图,你想设置

    'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.AllowAny']

    不需要对用户进行身份验证。然后在视图上显式设置更严格的权限(例如permissions_classes = [IsAuthenticated]DEFAULT_AUTHENTICATION_CLASS 可以保持原样。

    注意:通常建议反其道而行之。像这样意外暴露不安全的端点很容易,并可能在您的 API 中造成安全漏洞。默认值应该是安全的,然后应该手动解除异常。

    【讨论】:

    • 关于您的“注意:通常建议反过来做”,我很喜欢,但是我将如何在每个视图/方法中指定我不想需要身份验证?
    • 对于基于类的视图,您可以将权限类设置为空列表。 permission_classes = [ ] 对于基于函数的视图添加装饰器@permission_classes([])。 permission_classes 是从用于 FBV 的 rest_framework.decorators 导入的
    【解决方案2】:

    在settings.py中设置如下配置

    'DEFAULT_PERMISSION_CLASSES': [
       'rest_framework.permissions.IsAuthenticated',
    ]
    

    对于基于类的视图,您可以将权限类设置为空列表。

    class CoopList(APIView):
        permission_classes = []
      
        def get(self, request, format=None):
            pass
        
    

    对于基于函数的视图,添加装饰器@permission_classes

    from rest_framework.decorators import permission_classes
    
    @permission_classes([])
    def CoopList(request, format=None):
        pass 
    

    【讨论】:

      猜你喜欢
      • 2018-07-24
      • 2020-10-20
      • 2018-06-20
      • 2019-01-01
      • 1970-01-01
      • 2015-11-12
      • 2018-05-03
      • 2012-12-09
      • 2015-05-14
      相关资源
      最近更新 更多