Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 了解JWT并确认simplejwt在testcase中过期_Python_Django_Django Rest Framework_Django Rest Framework Simplejwt - Fatal编程技术网

Python 了解JWT并确认simplejwt在testcase中过期

Python 了解JWT并确认simplejwt在testcase中过期,python,django,django-rest-framework,django-rest-framework-simplejwt,Python,Django,Django Rest Framework,Django Rest Framework Simplejwt,我只是想了解到期情况,想知道当令牌到期时返回什么 为了探索这一点,我在django项目中编写了一个简单的测试用例,但我似乎无法让expire发生 视图.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(["POS

我只是想了解到期情况,想知道当令牌到期时返回什么

为了探索这一点,我在django项目中编写了一个简单的测试用例,但我似乎无法让expire发生

视图.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)

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)

目前我的测试用例如下:

测试.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)

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)

我希望这会导致某种授权错误,比如
401
之类的,但它似乎仍然会创建受保护的视图

self.assertEqual(response.status\u代码,HTTPStatus.UNAUTHORIZED)断言错误:201!=HTTPStatus.UNAUTHORIZED:401

为什么代币没有过期?或者,如何使令牌过期

也许我没有正确理解这一点


我的理解是,当
ACCESS\u-TOKEN\u-life
过期时,您不能再使用
ACCESS\u-TOKEN
,需要使用
refresh
令牌获取新令牌。正确吗?

插件必须在启动时进行设置并实例化其对象。在运行时,它不会再次读取设置,因此覆盖它们是无用的


正如您所做的,测试此功能的正确方法是使用一个separate设置模块进行测试,并将插件配置放在那里。

您最后一个问题的答案是肯定的。可能设置覆盖没有按预期工作。打印生成的令牌并检查到期日期,例如,将其粘贴到感谢中!是的,覆盖未按预期工作,expire将保持初始5分钟。我放弃了尝试使用
override\u settings
,最终创建了一个具有特定于测试环境设置的环境变量。不太理想,但我能确认401是以这种方式到期返回的。我猜是这样的。插件必须接受设置并“实例化”自身和启动时间,这样之后就不会再次读取设置,覆盖它们也没用了。很高兴它起作用了。我会把答案给未来的读者