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",
),
Это будет работать, но я бы не рекомендовал это делать в общем случае. Если вы хотите более детального "игнорирования" конкретных ошибок, то вам нужно переопределить больше функциональности, или использовать класс и вносить изменения напрямую.