mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
feat: implement secure HTTP-only cookie-based refresh token authentication
This commit is contained in:
@@ -95,6 +95,7 @@ DATABASES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CORS_ALLOWED_ORIGINS = env.list("CORS_ALLOWED_ORIGINS")
|
CORS_ALLOWED_ORIGINS = env.list("CORS_ALLOWED_ORIGINS")
|
||||||
|
CORS_ALLOW_CREDENTIALS = True # allow cookies with frontend
|
||||||
|
|
||||||
AUTH_USER_MODEL = "users.User"
|
AUTH_USER_MODEL = "users.User"
|
||||||
|
|
||||||
|
|||||||
@@ -20,3 +20,19 @@ def send_activation_email(user):
|
|||||||
If you did not create this account, please ignore this email."""
|
If you did not create this account, please ignore this email."""
|
||||||
send_mail(subject, message, settings.FROM_EMAIL, [user.email], fail_silently=False)
|
send_mail(subject, message, settings.FROM_EMAIL, [user.email], fail_silently=False)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def set_response_cookies(response, refresh_token):
|
||||||
|
_response = response
|
||||||
|
if "refresh" in _response.data:
|
||||||
|
del _response.data["refresh"] # remove refresh token from response body
|
||||||
|
_response.set_cookie(
|
||||||
|
key=settings.SIMPLE_JWT["AUTH_COOKIE"],
|
||||||
|
value=refresh_token,
|
||||||
|
max_age=settings.SIMPLE_JWT["REFRESH_TOKEN_LIFETIME"].total_seconds(),
|
||||||
|
httponly=settings.SIMPLE_JWT["AUTH_COOKIE_HTTPONLY"],
|
||||||
|
secure=settings.SIMPLE_JWT["AUTH_COOKIE_SECURE"],
|
||||||
|
samesite=settings.SIMPLE_JWT["AUTH_COOKIE_SAMESITE"],
|
||||||
|
domain=settings.SIMPLE_JWT["AUTH_COOKIE_DOMAIN"],
|
||||||
|
)
|
||||||
|
return _response
|
||||||
|
|||||||
+25
-1
@@ -4,8 +4,10 @@ from django.db import transaction
|
|||||||
from django.utils.http import urlsafe_base64_decode
|
from django.utils.http import urlsafe_base64_decode
|
||||||
from rest_framework import generics, permissions, status
|
from rest_framework import generics, permissions, status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
||||||
|
|
||||||
from users.utils import send_activation_email
|
from config import settings
|
||||||
|
from users.utils import send_activation_email, set_response_cookies
|
||||||
|
|
||||||
from .serializers import UserSerializer
|
from .serializers import UserSerializer
|
||||||
|
|
||||||
@@ -50,3 +52,25 @@ class MeView(generics.RetrieveAPIView):
|
|||||||
def get_object(self):
|
def get_object(self):
|
||||||
# Returns the user associated with the JWT token in the request
|
# Returns the user associated with the JWT token in the request
|
||||||
return self.request.user
|
return self.request.user
|
||||||
|
|
||||||
|
|
||||||
|
class TokenLoginView(TokenObtainPairView):
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
response = super().post(request, *args, **kwargs)
|
||||||
|
if response.status_code == status.HTTP_200_OK:
|
||||||
|
refresh_token = response.data["refresh"]
|
||||||
|
response = set_response_cookies(response, refresh_token)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class RefreshTokenView(TokenRefreshView):
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
refresh_token = request.COOKIES.get(settings.SIMPLE_JWT["AUTH_COOKIE"])
|
||||||
|
if not refresh_token:
|
||||||
|
return Response({"detail": "Refresh token not found"}, status=status.HTTP_401_UNAUTHORIZED)
|
||||||
|
request.data["refresh"] = refresh_token
|
||||||
|
response = super().post(request, *args, **kwargs)
|
||||||
|
if response.status_code == status.HTTP_200_OK:
|
||||||
|
new_refresh_token = response.data["refresh"]
|
||||||
|
response = set_response_cookies(response, new_refresh_token)
|
||||||
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user