Понимание JWT и подтверждение истечения срока действия simplejwt в тестовом примере

Я просто пытаюсь понять djangorestframework-simplejwt истечение срока действия и хотите знать, что будет возвращено, когда срок действия токена истечет.

Чтобы изучить это, я написал простой тестовый пример в моем проекте django, но я не могу добиться истечения срока действия.

views.py

import json
from http import HTTPStatus

from django.http import JsonResponse
from rest_framework.decorators import api_view

from .models import Visitor


@api_view(["POST"])
def visitor_post(request):
    body_unicode = request.body.decode("utf-8")
    if not body_unicode.strip():
        return JsonResponse({"status": HTTPStatus.BAD_REQUEST}, status=HTTPStatus.BAD_REQUEST)

    body = json.loads(body_unicode)
    submitted_datetime = body["submitted_datetime"]

    visitor = Visitor(
        representative_name=body["representative_name"],
        visitor_type=body["visitor_type"],
        visitor_count=body["visitor_count"],
        submitted_datetime=submitted_datetime,
    )
    visitor.save()
    return JsonResponse({"status": HTTPStatus.CREATED}, status=HTTPStatus.CREATED)

В настоящее время мой тестовый пример выглядит следующим образом:

tests.py

import datetime
import json
from time import sleep
from http import HTTPStatus
from typing import Optional, Tuple

from accounts.models import CustomUser
from django.urls import reverse
from django.utils import timezone
from django.test import override_settings
from rest_framework.test import APIClient, APITestCase


EXPIRE_WAIT_SECONDS = 5
SIMPLE_JWT_EXPIRE_TEST_SETTINGS = {
    "ACCESS_TOKEN_LIFETIME": datetime.timedelta(seconds=EXPIRE_WAIT_SECONDS),
    "REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=14),
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": False,
    "ALGORITHM": "HS256",
    "SIGNING_KEY": 'kkdkasjf;a',
    "VERIFYING_KEY": None,
    "AUTH_HEADER_TYPES": ("JWT",),
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
}


class ViewsTestCase(APITestCase):
    def setUp(self):
        self.valid_user = CustomUser(last_name="user", first_name="valid", username="validuser", email="[email protected]")
        self.valid_user_password = "mysecretpassword"
        self.valid_user.set_password(self.valid_user_password)
        self.valid_user.save()
        self.apiclient = APIClient()

    def _get_jwt_token(self, username: Optional[str] = None, password: Optional[str] = None) -> Tuple[str, str]:
        if not username:
            username = self.valid_user.username
        if not password:
            password = self.valid_user_password
        body = {"username": username, "password": password}
        url = reverse("token_obtain_pair")
        response = self.apiclient.post(url, data=body, format="json")
        self.assertEqual(response.status_code, 200)
        token_data = json.loads(response.content)
        return token_data["access"], token_data["refresh"]

    @override_settings(SIMPLE_JWT=SIMPLE_JWT_EXPIRE_TEST_SETTINGS)
    def test_visitor_post_token_expire(self):
        access_token, _ = self._get_jwt_token()

        now = timezone.now()
        data = {
            "representative_name": "Somename",
            "visitor_count": 1,
            "submitted_datetime": now.isoformat(),
        }
        sleep(EXPIRE_WAIT_SECONDS + 1)
        self.apiclient.credentials(HTTP_AUTHORIZATION=f"JWT {access_token}")
        url = "/visitors/"
        response = self.apiclient.post(url, data=data, format="json")
        self.assertEqual(response.status_code, HTTPStatus.UNAUTHORIZED)

Я ожидаю, что это приведет к какой-то ошибке авторизации, такой как 401 или что-то в этом роде, но, похоже, все же создается защищенное представление.

self.assertEqual (response.status_code, HTTPStatus.UNAUTHORIZED) AssertionError: 201! = HTTPStatus.UNAUTHORIZED: 401

Почему токен не истекает? Или как я могу истечь срок действия токена?

Может, я не правильно понимаю.

Насколько я понимаю, когда истекает ACCESS_TOKEN_LIFETIME, вы больше не можете использовать access_token и вам нужно получить новый токен, используя токен refresh. Это правильно?


person monkut    schedule 05.06.2020    source источник
comment
Ответ на твой последний вопрос - да. Возможно, переопределение настроек не работает должным образом. Распечатайте сгенерированный токен и проверьте дату истечения срока, например, вставив его в jwt.io   -  person gmc    schedule 05.06.2020
comment
Спасибо! Да, переопределение работает не так, как ожидалось, и срок действия составляет 5 минут.   -  person monkut    schedule 09.06.2020
comment
Я отказался от попыток использовать override_settings и в итоге создал переменную среды со специфическими настройками тестовой среды. Не идеально, но я смог подтвердить, что 401 возвращается по истечении срока действия таким образом.   -  person monkut    schedule 09.06.2020
comment
Я так и догадался. Плагин должен принять настройки и «создать экземпляр» самого себя и времени загрузки, чтобы после этого он не считывал настройки снова, и их было бесполезно переопределять. Рад, что это сработало. Собираюсь опубликовать ответ для будущих читателей   -  person gmc    schedule 09.06.2020


Ответы (1)


Плагин должен принимать настройки и создавать экземпляры своих объектов во время загрузки. Во время выполнения он не считывает настройки снова, поэтому переопределять их бесполезно.

Как и вы, правильный способ протестировать эту функцию - иметь отдельный модуль настроек для тестирования и поместить туда конфигурацию плагина.

person gmc    schedule 09.06.2020