Guidance Needed for Building a Django Project with Custom User Management and JWT Authentication

Hi StackOverflow Community,

I’m working on a Django project with specific requirements and technical constraints, and I’m looking for guidance on how to approach it. Here are the details:

Business Requirements:
Login

Users should be able to log in, and the system should handle successful and failed logins, account lockouts, and password recovery.
Logout with Session Store

Implement secure logout, handle session timeouts, and ensure session persistence across browser tabs.
User Management

Admins should be able to create, edit, deactivate user accounts, and view user activity logs.
Roles and Permissions

Admins should manage roles and permissions, assign roles to users, and modify role permissions.
Technical Specifications:
APIs: Must follow RESTful standards.
Authentication: JWT is the preferred token type.
Database: MongoDB.
ORM: Official Django ORM should not be used.
Model Management: Prefer using Pydantic.
Coding Standards: Follow PEP8 for Python.
APIs Framework: Use django-rest-framework.
Class-Based Design: The implementation should be class-based and object-oriented (no functional programming).
Current Knowledge and Setup:
I am familiar with Django and REST frameworks but need guidance on integrating MongoDB without using Django ORM, managing models with Pydantic, and implementing JWT authentication.
Questions:
Setup Guidance: What are the best practices for integrating Django with MongoDB using Djongo and Pydantic for model management?
JWT Authentication: How should I configure JWT authentication with django-rest-framework-jwt?
Class-Based Views: Can someone provide examples or guidelines on structuring class-based views for the requirements listed?
Session Management: How can I handle session management, including automatic logout and session persistence across browser tabs?
Any help or pointers to resources would be greatly appreciated!

Thank you!
`

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.hashers import make_password, check_password
from .serializers import RegistrationSerializer, LoginSerializer
from .models import UserModel, LoginModel
from pymongo import MongoClient
from django.conf import settings
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from account.custom_jwt import CustomJWTAuthentication
client = MongoClient(settings.MONGO_URI)
db = client.get_database()
user_collection = db.users
class RegisterView(APIView):
def post(self, request):
serializer = RegistrationSerializer(data=request.data)
if not serializer.is_valid():
return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
user_data = serializer.validated_data
user_data["username"] = user_data["username"].lower() # Convert username to lowercase
if user_collection.find_one({"username": user_data["username"]}):
return Response({"detail": "Username already exists"}, status=status.HTTP_400_BAD_REQUEST)
user = UserModel(**user_data)
user.password = make_password(user.password)
user_dict = user.dict(by_alias=True)
# Remove _id from the dictionary if it's None
if user_dict.get("_id") is None:
user_dict.pop("_id", None)
user_collection.insert_one(user_dict)
return Response({"detail": "User registered successfully"}, status=status.HTTP_201_CREATED)
class LoginView(APIView):
def post(self, request):
serializer = LoginSerializer(data=request.data)
if not serializer.is_valid():
return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
user_data = serializer.validated_data
user_data["username"] = user_data["username"].lower() # Convert username to lowercase
user = user_collection.find_one({"username": user_data["username"]})
if user and check_password(user_data["password"], user["password"]):
user_data = {**user, "_id": str(user.get("_id"))}
user_model = UserModel(**user_data)
refresh = RefreshToken.for_user(user_model)
response = Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'detail' : "Login successful"
}, status=status.HTTP_200_OK)
response.set_cookie(
key='refresh_token',
value=str(refresh),
httponly=True,
secure=True,
samesite='Strict',
max_age=3600 * 24 * 7 # 1 days
)
response.set_cookie(
key='access_token',
value=str(refresh.access_token),
httponly=True,
secure=True,
samesite='Strict',
max_age=3600 # 1 hour
)
return response
return Response({'detail': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)
class LogoutView(APIView):
permission_classes = [IsAuthenticated]
authentication_classes = [CustomJWTAuthentication]
def post(self, request):
try:
refresh_token = request.data.get("refresh")
if not refresh_token:
return Response({"detail": "Refresh token not provided"}, status=status.HTTP_400_BAD_REQUEST)
token = RefreshToken(refresh_token)
token.blacklist()
return Response(status=status.HTTP_205_RESET_CONTENT)
except Exception as e:
return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
class PublicAPI(APIView):
permission_classes = [IsAuthenticated]
authentication_classes = [CustomJWTAuthentication]
def get(self, request):
return Response({'msg':'kya haal chaal'})
</code>
<code>from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status, permissions from rest_framework_simplejwt.tokens import RefreshToken from django.contrib.auth.hashers import make_password, check_password from .serializers import RegistrationSerializer, LoginSerializer from .models import UserModel, LoginModel from pymongo import MongoClient from django.conf import settings from rest_framework.permissions import IsAuthenticated from rest_framework_simplejwt.authentication import JWTAuthentication from account.custom_jwt import CustomJWTAuthentication client = MongoClient(settings.MONGO_URI) db = client.get_database() user_collection = db.users class RegisterView(APIView): def post(self, request): serializer = RegistrationSerializer(data=request.data) if not serializer.is_valid(): return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) user_data = serializer.validated_data user_data["username"] = user_data["username"].lower() # Convert username to lowercase if user_collection.find_one({"username": user_data["username"]}): return Response({"detail": "Username already exists"}, status=status.HTTP_400_BAD_REQUEST) user = UserModel(**user_data) user.password = make_password(user.password) user_dict = user.dict(by_alias=True) # Remove _id from the dictionary if it's None if user_dict.get("_id") is None: user_dict.pop("_id", None) user_collection.insert_one(user_dict) return Response({"detail": "User registered successfully"}, status=status.HTTP_201_CREATED) class LoginView(APIView): def post(self, request): serializer = LoginSerializer(data=request.data) if not serializer.is_valid(): return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) user_data = serializer.validated_data user_data["username"] = user_data["username"].lower() # Convert username to lowercase user = user_collection.find_one({"username": user_data["username"]}) if user and check_password(user_data["password"], user["password"]): user_data = {**user, "_id": str(user.get("_id"))} user_model = UserModel(**user_data) refresh = RefreshToken.for_user(user_model) response = Response({ 'refresh': str(refresh), 'access': str(refresh.access_token), 'detail' : "Login successful" }, status=status.HTTP_200_OK) response.set_cookie( key='refresh_token', value=str(refresh), httponly=True, secure=True, samesite='Strict', max_age=3600 * 24 * 7 # 1 days ) response.set_cookie( key='access_token', value=str(refresh.access_token), httponly=True, secure=True, samesite='Strict', max_age=3600 # 1 hour ) return response return Response({'detail': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED) class LogoutView(APIView): permission_classes = [IsAuthenticated] authentication_classes = [CustomJWTAuthentication] def post(self, request): try: refresh_token = request.data.get("refresh") if not refresh_token: return Response({"detail": "Refresh token not provided"}, status=status.HTTP_400_BAD_REQUEST) token = RefreshToken(refresh_token) token.blacklist() return Response(status=status.HTTP_205_RESET_CONTENT) except Exception as e: return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST) class PublicAPI(APIView): permission_classes = [IsAuthenticated] authentication_classes = [CustomJWTAuthentication] def get(self, request): return Response({'msg':'kya haal chaal'}) </code>
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.hashers import make_password, check_password
from .serializers import RegistrationSerializer, LoginSerializer
from .models import UserModel, LoginModel
from pymongo import MongoClient
from django.conf import settings
from rest_framework.permissions import IsAuthenticated 
from rest_framework_simplejwt.authentication import JWTAuthentication
from account.custom_jwt import CustomJWTAuthentication

client = MongoClient(settings.MONGO_URI)
db = client.get_database()
user_collection = db.users


class RegisterView(APIView):
    def post(self, request):
        serializer = RegistrationSerializer(data=request.data)

        if not serializer.is_valid():
            return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
        
        user_data = serializer.validated_data
        user_data["username"] = user_data["username"].lower()  # Convert username to lowercase

        if user_collection.find_one({"username": user_data["username"]}):
            return Response({"detail": "Username already exists"}, status=status.HTTP_400_BAD_REQUEST)
        
        user = UserModel(**user_data)
        user.password = make_password(user.password)

        user_dict = user.dict(by_alias=True)
        
        # Remove _id from the dictionary if it's None
        if user_dict.get("_id") is None:
            user_dict.pop("_id", None)

        user_collection.insert_one(user_dict)
        return Response({"detail": "User registered successfully"}, status=status.HTTP_201_CREATED)

class LoginView(APIView):
    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({"detail": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
       
        user_data = serializer.validated_data
        user_data["username"] = user_data["username"].lower()  # Convert username to lowercase

        user = user_collection.find_one({"username": user_data["username"]})

        if user and check_password(user_data["password"], user["password"]):
            user_data = {**user, "_id": str(user.get("_id"))}
            user_model = UserModel(**user_data)
            refresh = RefreshToken.for_user(user_model)

            response =  Response({
                'refresh': str(refresh),
                'access': str(refresh.access_token),
                'detail' : "Login successful"
            }, status=status.HTTP_200_OK)

            response.set_cookie(
                key='refresh_token',
                value=str(refresh),
                httponly=True,
                secure=True,
                samesite='Strict',
                max_age=3600 * 24 * 7  # 1 days
            )


            response.set_cookie(
                key='access_token',
                value=str(refresh.access_token),
                httponly=True,
                secure=True,
                samesite='Strict',
                max_age=3600  # 1 hour
            )

            return response
        
        return Response({'detail': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)

class LogoutView(APIView):
    permission_classes = [IsAuthenticated]
    authentication_classes = [CustomJWTAuthentication]

    def post(self, request):
        try:
            refresh_token = request.data.get("refresh")
            if not refresh_token:
                return Response({"detail": "Refresh token not provided"}, status=status.HTTP_400_BAD_REQUEST)
            
            token = RefreshToken(refresh_token)
            token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception as e:
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)

class PublicAPI(APIView):
    permission_classes = [IsAuthenticated]
    authentication_classes = [CustomJWTAuthentication]

    def get(self, request):
        return Response({'msg':'kya haal chaal'})

New contributor

Ravinder is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật