mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
feat: implement secure cookie-based authentication with login, refresh, and logout endpoints
This commit is contained in:
+30
-1
@@ -1 +1,30 @@
|
|||||||
# Create your tests here.
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.urls import reverse
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class AuthTests(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.password = "password123"
|
||||||
|
self.user = User.objects.create_user(
|
||||||
|
email="test@example.com", password=self.password, full_name="Test User", is_active=True
|
||||||
|
)
|
||||||
|
self.login_url = reverse("token_obtain_pair")
|
||||||
|
self.refresh_url = reverse("token_refresh")
|
||||||
|
self.logout_url = reverse("logout")
|
||||||
|
|
||||||
|
def test_login_sets_secure_cookie(self):
|
||||||
|
data = {"email": self.user.email, "password": self.password}
|
||||||
|
response = self.client.post(self.login_url, data)
|
||||||
|
cookie_name = settings.SIMPLE_JWT["AUTH_COOKIE"]
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertIn("access", response.data)
|
||||||
|
self.assertNotIn("refresh", response.data)
|
||||||
|
self.assertIn(cookie_name, response.cookies)
|
||||||
|
# verify the cookie has a value
|
||||||
|
self.assertTrue(response.cookies[cookie_name].value)
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
|
||||||
|
|
||||||
from users.views import ActivationView
|
from .views import ActivationView, LogoutView, MeView, RegisterView, TokenLoginView, TokenRefreshView
|
||||||
|
|
||||||
from .views import MeView, RegisterView
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("register/", RegisterView.as_view(), name="register"),
|
path("register/", RegisterView.as_view(), name="register"),
|
||||||
# Login and get access and refresh tokens
|
# Login and get access and refresh tokens
|
||||||
path("login/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
|
path("login/", TokenLoginView.as_view(), name="token_obtain_pair"),
|
||||||
# Get a new access token using a refresh token
|
# Get a new access token using a refresh token
|
||||||
path("refresh/", TokenRefreshView.as_view(), name="token_refresh"),
|
path("refresh/", TokenRefreshView.as_view(), name="token_refresh"),
|
||||||
# Get current user info
|
# Get current user info
|
||||||
path("me/", MeView.as_view(), name="me"),
|
path("me/", MeView.as_view(), name="me"),
|
||||||
# Activate user account
|
# Activate user account
|
||||||
path("activate/<str:uidb64>/<str:token>/", ActivationView.as_view(), name="activate"),
|
path("activate/<str:uidb64>/<str:token>/", ActivationView.as_view(), name="activate"),
|
||||||
|
# Logout and delete the access token
|
||||||
|
path("logout/", LogoutView.as_view(), name="logout"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ class MeView(generics.RetrieveAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class TokenLoginView(TokenObtainPairView):
|
class TokenLoginView(TokenObtainPairView):
|
||||||
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
response = super().post(request, *args, **kwargs)
|
response = super().post(request, *args, **kwargs)
|
||||||
if response.status_code == status.HTTP_200_OK:
|
if response.status_code == status.HTTP_200_OK:
|
||||||
@@ -64,6 +66,8 @@ class TokenLoginView(TokenObtainPairView):
|
|||||||
|
|
||||||
|
|
||||||
class RefreshTokenView(TokenRefreshView):
|
class RefreshTokenView(TokenRefreshView):
|
||||||
|
permission_classes = (permissions.IsAuthenticated,)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
refresh_token = request.COOKIES.get(settings.SIMPLE_JWT["AUTH_COOKIE"])
|
refresh_token = request.COOKIES.get(settings.SIMPLE_JWT["AUTH_COOKIE"])
|
||||||
if not refresh_token:
|
if not refresh_token:
|
||||||
@@ -74,3 +78,18 @@ class RefreshTokenView(TokenRefreshView):
|
|||||||
new_refresh_token = response.data["refresh"]
|
new_refresh_token = response.data["refresh"]
|
||||||
response = set_response_cookies(response, new_refresh_token)
|
response = set_response_cookies(response, new_refresh_token)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class LogoutView(generics.GenericAPIView):
|
||||||
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
response = Response({"detail": "Successfully logged out"}, status=status.HTTP_200_OK)
|
||||||
|
# Clear the secure cookie
|
||||||
|
response.delete_cookie(
|
||||||
|
key=settings.SIMPLE_JWT["AUTH_COOKIE"],
|
||||||
|
domain=settings.SIMPLE_JWT.get("AUTH_COOKIE_DOMAIN"),
|
||||||
|
samesite=settings.SIMPLE_JWT.get("AUTH_COOKIE_SAMESITE"),
|
||||||
|
path="/",
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user