Ну, согласно документации , вы не можете использовать authentication_classes
, потому что вы не имеете никакого отношения к модели пользователя с учетными данными.И вы также не можете использовать классы разрешений, потому что permissions.isAuthenticated
проверяет, есть ли в запросе какой-либо пользовательский экземпляр и проверен ли он, как if request.user.is_authenticated
.
Так что вы можете использовать этот подход вместо декоратора.Попробуйте так:
import binascii
import base64
from django.utils.translation import ugettext_lazy as _
from rest_framework import status
from rest_framework.authentication import get_authorization_header
from rest_framework import HTTP_HEADER_ENCODING
def check_authenticated(function):
def wrapper(obj, request, *args, **kw):
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != b'basic':
msg = _("Not basic authentication.")
return Response(data={'error': msg}, status=status.HTTP_401_UNAUTHORIZED)
if len(auth) == 1:
msg = _('Invalid basic header. No credentials provided.')
return Response(data={'error': msg}, status=status.HTTP_401_UNAUTHORIZED)
elif len(auth) > 2:
msg = _('Invalid basic header. Credentials string should not contain spaces.')
return Response(data={'error': msg}, status=status.HTTP_401_UNAUTHORIZED)
try:
auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':')
except (TypeError, UnicodeDecodeError, binascii.Error):
msg = _('Invalid basic header. Credentials not correctly base64 encoded.')
return Response(data={'error': msg}, status=status.HTTP_401_UNAUTHORIZED)
userid, password = auth_parts[0], auth_parts[2]
# Your auth table specific codes
if AuthTable.objects.filter(username=userid, password=password).exists(): # my dummy code
return function(obj, request, *args, **kw)
else:
msg = _('User not found.')
return Response(data={'error': msg}, status=status.HTTP_401_UNAUTHORIZED)
return wrapper
Теперь используйте это в своем ViewSet следующим образом:
class EventDataViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
queryset = models.EventData.objects.all()
serializer_class = serializers.EventDataSerializer
authentication_classes = []
permission_classes = []
@check_authenticated
def create(self, request, *args, **kwargs):
return super(EventDataViewSet, self).create(request,*args, **kwargs)
@check_authenticated
def list(self, request, *args, **kwargs):
return super(EventDataViewSet, self).list(request,*args, **kwargs)
Но если у вас есть связь между auth_table
и User
моделью, то вы можетепереопределить BasicAuthetication
класс следующим образом:
class EventDataApiAuth(BasicAuthentication):
def authenticate_credentials(self, userid, password, request=None):
user = AuthData.objects.get(username=userid, password=password).user # assuming auth_table has a ForeignKey relation to User
return (user, None)
и использовать его в authentication_classes
.Надеюсь, это поможет !!