I'm just trying to understand djangorestframework-simplejwt expiration and want to know what is returned when the token expires.
To explore this a wrote a simple testcase in my django project, but I can't seem to get the expire to occur.
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)
Currently my testcase is as follows:
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="validuser@email.com")
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)
I expect this to result in some kind of authorization error, like a 401
or something, but it seems to still create the protected view.
self.assertEqual(response.status_code, HTTPStatus.UNAUTHORIZED)AssertionError: 201 != HTTPStatus.UNAUTHORIZED: 401
Why doesn't the token expire? Or, how can I make the token expire?
Maybe I don't understand this correctly.
I my understanding is that when ACCESS_TOKEN_LIFETIME
expires you can no longer use the access_token
and need to get a new token using the refresh
token. Is that correct?
The plugin must take the settings and instantiate its objects at boot time. At runtime, it does not read the settings again, so it is useless to override them.
As you did, the proper way to test this feature is to have a sepparate settings module for testing and put the plugin config there.