Django Rest Framework + SimpleJWT возвращает 401 на незащищенных маршрутах

Я настроил DRF на использование JWT в качестве схемы аутентификации, и по большей части она работает правильно, однако когда токен пользователя & refresh token больше не действителен, вместо того, чтобы возвращать 200 как неавторизованный пользователь для незащищенных маршрутов и отображать сайт, как будто они больше не вошли в систему, бэкенд возвращает 401. Я новичок в схеме аутентификации Django / настройке промежуточного ПО, но я предполагаю, что если по умолчанию стоит AllowAny, то плохой токен будет проигнорирован. Есть ли конфигурация, которую я упускаю.

Из документации DRF

Если не указано, этот параметр по умолчанию разрешает неограниченный доступ:

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

мой settings.py

REST_FRAMEWORK = {
    ...
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.BasicAuthentication",
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
}

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": datetime.timedelta(minutes=15),
    "REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=2),
    ...
}

Пример ViewSet, который возвращает 401 с плохим токеном доступа

class PromoApiSet(ViewSet):
    serializer_class = PromoSerializer

    def get_queryset(self, *args, **kwargs):
        time_now = timezone.now()
        return PromoNotification.objects.filter(
            end_date__gte=time_now, start_date__lte=time_now
        )

    # @method_decorator(cache_page(120))
    def list(self, request):
        promos = self.get_queryset()

        serializer = self.serializer_class(promos, many=True)
        promos_data = serializer.data

        response_data = {"promos": promos_data}

        return Response(response_data)

Недействительные, неправильно сформированные или иным образом неверные учетные данные вызовут ошибку 401, см. исходный код класса JWTAuthentication.

Мне кажется, это имеет смысл, но если вы хотите, чтобы поведение было "молча игнорировать этот заголовок, если произошла ошибка", то вам нужно переопределить метод и, ну, игнорировать ошибки:

class MyJWTAuth(JWTAuthentication):
    def authenticate(self, request):
        try:
            return super().authenticate(self, request)
        except (InvalidToken, AuthenticationFailed):
            return None

# in your settings, use your new class
"DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.BasicAuthentication",
        "my.project.module.MyJWTAuth",
),

Это будет работать, но я бы не рекомендовал это делать в общем случае. Если вы хотите более детального "игнорирования" конкретных ошибок, то вам нужно переопределить больше функциональности, или использовать класс и вносить изменения напрямую.

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