Класс пользовательской аутентификации Django не читает AllowAny

Вот класс аутентификации REST:

def get_authorization_header(request):
    raw_token = request.COOKIES.get('auth_token', ) or None
    auth = request.META.get('HTTP_AUTHORIZATION', )
    if isinstance(auth, str):
        auth = auth.encode(HTTP_HEADER_ENCODING)
    return auth


class JWTAuthentication(BaseAuthentication):
    keyword = 'auth_token'

    def authenticate(self, request):
        raw_token = request.COOKIES.get('auth_token', ) or None
        if raw_token is None:
            return None

        return self.authenticate_credentials(raw_token)

    def authenticate_credentials(self, key):
        try:
            user_model = get_user_model()
            payload = jwt.decode(key, settings.SECRET_KEY, algorithms="HS256")
            user = user_model.objects.get(email=payload['email'])
        except (jwt.DecodeError, user_model.DoesNotExist):
            raise exceptions.ParseError('Invalid token')
        except jwt.ExpiredSignatureError:
            raise exceptions.ParseError('Token has expired')
        if not user.is_active:
            raise exceptions.AuthenticationFailed('User inactive or deleted')

        return (user, payload)

    def authenticate_header(self, request):
        return self.keyword

А вот вид:

class GoogleLogin(APIView):

    permission_classes = [AllowAny]
    def post(self, request):
        data = request.data
        response = Response()
        token = data.get('tokenId', None)

        if not token:
            raise exceptions.AuthenticationFailed('No credentials provided.')

        try:

            token_info = id_token.verify_oauth2_token(token, requests.Request(), google_app_id)
            email = token_info['email']
            user = authenticate(email)

            if not user:
                serializer = RegisterSerializer(data={'email': token_info['email'], 'first_name': token_info['given_name'], 'last_name': token_info['family_name']})
                serializer.is_valid(raise_exception=True)
                serializer.save()

            jwt_token = gen_token(email)

            response.set_cookie(
                key='auth_token',
                value=jwt_token,
                expires=datetime.datetime.utcnow() + datetime.timedelta(days=30),
                secure=False,
                httponly=True,
                samesite='Lax'
            )

            return response
        except ValueError:
            return Response('Invalid TokenId.', status=status.HTTP_400_BAD_REQUEST)

Я пытаюсь реализовать социальный логин Google, где фронтенд (ReactJS) посылает tokenId на бэкенд (Django) для проверки токена, затем возвращает ответ с JWT-токеном, хранящимся в куках (имя куки auth_token), как показано в этой строке response.set_cookie теперь, когда Я пытаюсь войти в систему, когда у меня нет токена аутентификации (у меня нет auth_token в моих cookies) все работает нормально, но когда я пытаюсь войти в систему, когда у меня есть просроченный токен аутентификации, я получаю сообщение 'Token has expired', даже если я установил класс разрешения AllowAny

Я думаю, что я неправильно реализовал свой класс аутентификации, не могу понять, где проблема

AllowAny происходит после аутентификации для проверки наличия прав у зарегистрированного или анонимного пользователя. Если аутентификация не прошла, запрос блокируется до получения разрешения.

В вашем коде, если нет токена, анонимный пользователь может получить доступ к представлению входа. Auth принимает запрос. Для ExpiredToken нет возможности передать auth, потому что вы поднимаете исключение.

На самом деле, ваш код делает все правильно. Если срок действия токена истек, фронт должен удалить недействительный токен, перенаправить на страницу входа и заставить пользователя снова нажать кнопку входа без COOKIE.

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