Почему разрешения не переопределяются для набора представлений?

Я создал набор представлений для аутентификации. Поскольку это набор представлений для аутентификации, я хочу, чтобы этот набор представлений был доступен и для неавторизованных пользователей. Следуя документации DRF, вот что у меня получилось:

class AuthenticationViewSet(viewsets.ViewSet):
    permission_classes = [AllowAny]

    def create_user(self, request: Request) -> Response:
        #code for creating a user

Поскольку я хочу, чтобы другие наборы представлений были доступны только авторизованным пользователям, я установил следующее в settings.py:

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "authentication.token_auth.ExpiringTokenAuthentication"
    ]
}

Когда я делаю вызов API к конечной точке create_user, я получаю ошибку, говорящую: "Токен не найден". Почему это происходит? Разве разрешения не должны переопределяться на основе списка permission_classes в наборе представлений?

Для справки, мой класс аутентификации:

class ExpiringTokenAuthentication(TokenAuthentication):
    def authenticate(self, request):
        if COOKIE_KEY in request.COOKIES:
            token_key = request.COOKIES[COOKIE_KEY]
        else:
            raise exceptions.AuthenticationFailed("No token found")

        try:
            token = Token.objects.get(key=token_key)
        except Token.DoesNotExist:
            return exceptions.AuthenticationFailed("Invalid token")

        if isTokenExpired(token):
            raise exceptions.AuthenticationFailed("Token has expired")

        user = token.user

        return (user, token)


def isTokenExpired(token):
    currentTime = datetime.now(datetime.UTC)
    currentTimeUTC = currentTime.replace(tzinfo=pytz.UTC)
    return token.created < currentTimeUTC - timedelta(hours=TOKEN_EXPIRE_HOURS)

У меня ушло гораздо больше времени, чем следовало бы, чтобы понять это. Но вы должны добавить и permission_classes=[], и authentication_classes=[] в наборе представлений, если хотите разрешить неограниченный доступ к набору представлений.

Аутентификация и разрешения - это две разные концепции в DRF. Аутентификация - это выяснение того, кто является пользователем. Разрешения - это выяснение того, разрешено ли аутентифицированному пользователю выполнять запрошенное действие.

В этом случае, хотя я обходил разрешения, устанавливая permission_classes=[], я все равно получал 401, потому что запрос исходил не от аутентифицированного пользователя, так как DRF проверял запрос, чтобы понять, кто его делает.

Таким образом, код для набора представлений выглядит так:

class AuthenticationViewSet(viewsets.ViewSet):
    permission_classes = []
    authentication_classes = []

    def create_user(self, request: Request) -> Response:
        # code for creating a user

Вернуться на верх