如何在Django REST Framework中禁用身份验证

mac*_*ost 42 authentication django-rest-framework

我正在一个商店网站上工作,每个用户都将是匿名的(好吧,至少需要付费),我正在尝试使用Django REST Framework来提供产品API,但它一直在抱怨:

"detail": "Authentication credentials were not provided."
Run Code Online (Sandbox Code Playgroud)

我发现了一些与身份验证相关的设置,但我找不到类似的东西ENABLE_AUTHENTICATION = True.如何简单地禁用身份验证,并让站点的任何访问者访问API?

ina*_*inc 49

您可以在设置中为权限身份验证类提供空的默认值.

REST_FRAMEWORK = {
    # other settings...

    'DEFAULT_AUTHENTICATION_CLASSES': [],
    'DEFAULT_PERMISSION_CLASSES': [],
}
Run Code Online (Sandbox Code Playgroud)

  • 如何在DRF中仅跳过一个类的身份验证 (16认同)
  • @roanjain添加属性`authentication_classes = []` - 顾名思义,设置dict只是一个默认值. (5认同)
  • @OllieFord 这听起来像是一场灾难。如果有人将默认身份验证设置为无,而后来另一个人忘记为任何端点指定任何身份验证类,则该端点可能会不受保护。我想继续使用“黑名单”实践而不是“白名单”,只需为我想要保持开放的特定端点指定一个神奇的匿名身份验证和权限类。 (2认同)
  • @CsabaToth我不明白我上面的评论不是你想要的吗?在设置中保留`'DEFAULT_AUTHENTICATION_CLASSES'= ['YourAuthenticationClass']`,然后在要保留打开的视图上放置`authentication_classes = []`。如果未提供此属性,则将使用设置中的默认值-在此不会造成灾难。 (2认同)
  • @CsabaToth我认为你一定误读了我的建议 - 我*不是*说在设置中禁用身份验证,我是说在你想要无需身份验证的情况下访问的特定端点上覆盖它。我同意替代方案(设置中没有默认值,在每个视图上指定)是一场等待发生的噩梦。 (2认同)

Aas*_*oni 38

您还可以禁用特定类或方法的身份验证,只需保留特定方法的装饰器.

from rest_framework.decorators import authentication_classes, permission_classes

@api_view(['POST'])    
@authentication_classes([])
@permission_classes([])
def items(request):
   return Response({"message":"Hello world!"})
Run Code Online (Sandbox Code Playgroud)

  • 有没有人成功实现这个片段?我试过,不工作. (3认同)
  • 看这里:http://stackoverflow.com/questions/35970970/django-rest-framework-permission-classes-of-viewset-method (2认同)
  • 是的,在我的情况下工作正常,我已将其与用户注册视图集一起使用,您能告诉我您遇到了什么错误吗? (2认同)
  • 仅当您使用“@api_view”装饰器时,这才有效:https://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme (2认同)

Sum*_*ran 8

如果您想为某个基于类的视图禁用身份验证,那么您可以使用,

class PublicEndPoint(APIView):
    authentication_classes = [] #disables authentication
    permission_classes = [] #disables permission
    
    def get(self, request):
        pass
Run Code Online (Sandbox Code Playgroud)

当您只想公开特定的端点时,这很有用。

  • 这是要走的路。谢谢你! (2认同)
  • 如果您想禁用同一“APIView”类中的特定端点怎么办?比如“get”,但不是“post”? (2认同)

小智 7

要全局启用身份验证,请将其添加到 django 设置文件中:

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),
Run Code Online (Sandbox Code Playgroud)

然后将以下装饰器添加到您的方法中以启用未经身份验证的访问

from rest_framework.decorators import authentication_classes, permission_classes

@api_view(['POST'])
@authentication_classes([])
@permission_classes([])
def register(request):
  try:
    username = request.data['username']
    email = request.data['email']
    password = request.data['password']
    User.objects.create_user(username=username, email=email, password=password)
    return Response({ 'result': 'ok' })
  except Exception as e:
    raise APIException(e)
Run Code Online (Sandbox Code Playgroud)


Sli*_*eam 6

如果使用 APIView,您可以为视图创建权限,示例如下:

网址.py

url(r'^my-endpoint', views.MyEndpoint.as_view())
Run Code Online (Sandbox Code Playgroud)

权限.py

class PublicEndpoint(permissions.BasePermission):
    def has_permission(self, request, view):
        return True
Run Code Online (Sandbox Code Playgroud)

视图.py

from permissions import PublicEndpoint

class MyEndpoint(APIView):

    permission_classes = (PublicEndpoint,)

    def get(self, request, format=None):
        return Response({'Info':'Public Endpoint'})
Run Code Online (Sandbox Code Playgroud)

  • 您的 PublicEndpoint 实现与 rest_framework.permissions.AllowAny 相同 (4认同)
  • @MikePlacentra 是的,整个答案可以替换为 from rest_framework.permissions import AllowAny & permission_classes = (AllowAny,) (4认同)

Uma*_*har 6

您也可以通过将其应用于类或方法,将其应用于一个特定的端点。只需要将django rest框架的AllowAny权限应用于特定的方法或类。

views.py

from rest_framework.permissions import AllowAny

from .serializers import CategorySerializer
from catalogue.models import Category   

@permission_classes((AllowAny, ))
class CategoryList(generics.ListAPIView):
    serializer_class = serializers.CategorySerializer
    queryset = Category.objects.all()
Run Code Online (Sandbox Code Playgroud)

您可以通过为权限设置使用空列表或元组来获得相同的结果,但是您可能会发现指定此类非常有用,因为它使意图明确。