Skip to content

Commit d4c34e9

Browse files
committed
feat[bckend-middleware]:Implemented custom middleware to check for blacklisted access tokens in Redis.
1 parent d4b819d commit d4c34e9

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

services/api/kalvi/api/views/auth.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from rest_framework_simplejwt.views import TokenRefreshView as SimpleJWTTokenRefreshView
66
from django.contrib.auth import authenticate
77
from db.renderer import UserRenderer
8-
from rest_framework_simplejwt.tokens import RefreshToken
8+
from rest_framework_simplejwt.tokens import RefreshToken, AccessToken
99
from rest_framework_simplejwt.exceptions import TokenError
1010
from rest_framework.permissions import AllowAny
1111
from django.utils.encoding import smart_str
@@ -155,19 +155,24 @@ def post(self, request, uid, token, format=None):
155155
except ValidationError as e:
156156
return Response({'error': e.detail}, status=status.HTTP_400_BAD_REQUEST)
157157

158-
# Viewset class for blocking refresh tokens after logging out.
158+
# Viewset class for blocking tokens after logging out.
159159
class SignOutEndpoint(APIView):
160160
def post(self, request):
161161
refresh_token = request.data.get('refresh_token')
162-
if refresh_token:
162+
access_token = request.headers.get('Authorization').split(' ')[1] #We are catching access tokens from authorization header.
163+
if refresh_token:
163164
try:
164165
# Connect to Redis
165166
redis_conn = get_redis_connection()
166-
token = str(RefreshToken(refresh_token))
167-
# Blacklist the token in Redis
168-
expiration_time = int(settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'].total_seconds())
169-
redis_conn.set(token, 'blacklisted')
170-
redis_conn.expire(token, expiration_time)
167+
refresh_token_str = str(RefreshToken(refresh_token))
168+
access_token_str = str(AccessToken(access_token))
169+
# Blacklist tokens in Redis
170+
refresh_exp_time = int(settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'].total_seconds())
171+
access_exp_time = int(settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'].total_seconds())
172+
with redis_conn.pipeline() as pipe:
173+
pipe.set(refresh_token_str, 'blacklisted', ex=refresh_exp_time)
174+
pipe.set(access_token_str, 'blacklisted', ex=access_exp_time)
175+
pipe.execute()
171176
return Response({'message': 'Logged out successfully'}, status=status.HTTP_200_OK)
172177
except Exception:
173178
return Response({'error': 'Please try after some time'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

services/api/kalvi/middlewares/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from rest_framework_simplejwt.tokens import AccessToken
2+
from rest_framework import status
3+
from kalvi.api.views.auth import get_redis_connection
4+
from django.http import JsonResponse
5+
6+
class CustomOutstandingTokenMiddleware:
7+
"""
8+
This middleware checks for blacklisted tokens in Redis. It does not perform any token validation.
9+
"""
10+
def __init__(self, get_response=None):
11+
self.get_response = get_response
12+
13+
def __call__(self, request):
14+
try:
15+
auth_header = request.headers.get('Authorization')
16+
if not auth_header:
17+
return self.get_response(request)
18+
token = auth_header.split()[1]
19+
token_obj = str(AccessToken(token))
20+
redis_conn = get_redis_connection()
21+
# Check if the token is blacklisted in Redis
22+
if redis_conn.exists(token_obj):
23+
return JsonResponse({'error': "Access token is blacklisted"}, status=status.HTTP_401_UNAUTHORIZED)
24+
else:
25+
return self.get_response(request)
26+
except Exception:
27+
return self.get_response(request)

services/api/kalvi/settings.py

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"django.middleware.common.CommonMiddleware",
5858
"django.middleware.csrf.CsrfViewMiddleware",
5959
"django.contrib.auth.middleware.AuthenticationMiddleware",
60+
"kalvi.middlewares.tokenMiddleware.CustomOutstandingTokenMiddleware",
6061
"django.contrib.messages.middleware.MessageMiddleware",
6162
"django.middleware.clickjacking.XFrameOptionsMiddleware",
6263
]

0 commit comments

Comments
 (0)