Как проверить токен доступа и перенаправить пользователя, если он истек, в представление refreshtoen в простой jwt-аутентификации с django rest framework
Как я могу перенаправить пользователя для получения нового токена доступа в представлении refresh token, если срок действия токена доступа истек? Я реализовал аутентификацию на основе cookie с простой библиотекой jwt в django rest framework. Токен обновления и токен доступа генерируются автоматически. Но мне нужно проверить токен, например, если пользователь вошел в систему, он получил токен доступа. И когда он пытается добавить новый пост, я должен сначала проверить, не истек ли срок действия токена доступа. Если он не истек, то он может добавить пост, в противном случае я сгенерирую новый токен доступа на основе уже полученного им токена обновления.
.Views.py
class LoginView(APIView):
def post(self, request, format=None):
data = request.data
response = Response()
email = data.get('email', None)
password = data.get('password', None)
user = authenticate(email=email, password=password)
if user is not None:
if user.is_active:
data = get_tokens_for_user(user)
response.set_cookie(
key = settings.SIMPLE_JWT['AUTH_COOKIE'],
value = data["access"],
expires = settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'],
secure = settings.SIMPLE_JWT['AUTH_COOKIE_SECURE'],
httponly = settings.SIMPLE_JWT['AUTH_COOKIE_HTTP_ONLY'],
samesite = settings.SIMPLE_JWT['AUTH_COOKIE_SAMESITE']
)
csrf.get_token(request)
response.data = {"Success" : "Login successfully","data":data}
return response
else:
return Response({"No active" : "This account is not active!!"}, status=status.HTTP_404_NOT_FOUND)
else:
return Response({"Invalid" : "Invalid email or password!!"}, status=status.HTTP_404_NOT_FOUND)
authenticate.py
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.conf import settings
from rest_framework.authentication import CSRFCheck
from rest_framework import exceptions
def enforce_csrf(request):
check = CSRFCheck()
check.process_request(request)
reason = check.process_view(request, None, (), {})
if reason:
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
class CustomAuthentication(JWTAuthentication):
def authenticate(self, request):
header = self.get_header(request)
if header is None:
raw_token = request.COOKIES.get(settings.SIMPLE_JWT['AUTH_COOKIE']) or None
else:
raw_token = self.get_raw_token(header)
if raw_token is None:
return None
validated_token = self.get_validated_token(raw_token)
enforce_csrf(request)
return self.get_user(validated_token), validated_token
urls.py
if api_settings.JWT_AUTH_COOKIE:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.serializers import RefreshJSONWebTokenSerializer
from rest_framework_jwt.views import RefreshJSONWebToken
RefreshJSONWebTokenSerializer._declared_fields.pop('token')
class RefreshJSONWebTokenSerializerCookieBased(RefreshJSONWebTokenSerializer):
def validate(self, attrs):
if 'token' not in attrs:
if api_settings.JWT_AUTH_COOKIE:
attrs['token'] = JSONWebTokenAuthentication().get_jwt_value(self.context['request'])
return super(RefreshJSONWebTokenSerializerCookieBased, self).validate(attrs)
RefreshJSONWebToken.serializer_class = RefreshJSONWebTokenSerializerCookieBased
urlpatterns = [
path('login/', views.LoginView.as_view(), name="login"),
path('refresh/',TokenRefreshView.as_view(), name="refresh"),
]
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'api.authenticate.JWTAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
# custom
'AUTH_COOKIE': 'access_token', # Cookie name. Enables cookies if value is set.
'AUTH_COOKIE_DOMAIN': None, # A string like "example.com", or None for standard domain cookie.
'AUTH_COOKIE_SECURE': False, # Whether the auth cookies should be secure (https:// only).
'AUTH_COOKIE_HTTP_ONLY' : True, # Http only cookie flag.It's not fetch by javascript.
'AUTH_COOKIE_PATH': '/', # The path of the auth cookie.
'AUTH_COOKIE_SAMESITE': 'Lax', # Whether to set the flag restricting cookie leaks on cross-site requests. This can be 'Lax', 'Strict', or None to disable the flag.
}