Everything about freelancing, programming, and graphic designing in one place.

Post Page Advertisement [Top]



A Django app is monolith, not a microservice, by default.
A microservice is a separately deployed Django project with its own auth boundary.

Below is the simplest, correct way to do this using JWT shared between two Django services.


Service 1, Auth Service

This is a standalone Django project whose only job is to issue JWTs.

settings.py

DJANGO_SECRET_KEY = "same-secret-between-all-microservices"

auth_service/auth.py

import jwt
import time
from django.conf import settings

JWT_ALGORITHM = "HS256"
JWT_EXP_SECONDS = 300

def issue_token(user_id: str) -> str:
    payload = {
        "sub": user_id,
        "iat": int(time.time()),
        "exp": int(time.time()) + JWT_EXP_SECONDS,
    }

    token = jwt.encode(
        payload,
        settings.DJANGO_SECRET_KEY,
        algorithm=JWT_ALGORITHM,
    )
    return token

views.py

from django.http import JsonResponse
from .auth import issue_token

def login(request):
    user_id = "123"  # assume validated user
    token = issue_token(user_id)
    return JsonResponse({"access_token": token})

This service only issues jwt tokens. When a user sends email and password to login the correct user.


Service 2, Business Service

This is a separate Django project, deployed independently.
Its database doesn't have users or auth related stuff.
It only knows how to read the content of auth service JWT token because of same django_secret_key.

settings.py

DJANGO_SECRET_KEY = "same-secret-between-all-microservices"

Custom JWT Middleware

middleware.py

import jwt
from django.conf import settings
from django.http import JsonResponse

class JWTAuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        auth_header = request.headers.get("Authorization")

        if not auth_header or not auth_header.startswith("Bearer "):
            return JsonResponse({"detail": "Unauthorized"}, status=401)

        token = auth_header.split(" ")[1]

        try:
            payload = jwt.decode(
                token,
                settings.DJANGO_SECRET_KEY,
                algorithms=["HS256"],
            )
        except jwt.ExpiredSignatureError:
            return JsonResponse({"detail": "Token expired"}, status=401)
        except jwt.InvalidTokenError:
            return JsonResponse({"detail": "Invalid token"}, status=401)

        request.user_id = payload["sub"]
        return self.get_response(request)

Register Middleware

settings.py

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "your_app.middleware.JWTAuthMiddleware",
]

Protected View in Service 2

from django.http import JsonResponse

def dashboard(request):
    return JsonResponse({
        "message": "Access granted",
        "user_id": request.user_id,
    })

How the services talk

  1. Client calls Auth Service → receives JWT
  2. Client calls Business Service with Authorization: Bearer <token>
  3. Business Service validates token locally
  4. No shared DB, no shared sessions, no Django apps crossing boundaries

That separation is what makes it a microservice. Separate apps, separate databases, linked together based on good old keys.


The important clarification

  • Multiple Django apps in one project is not microservices
  • One Django project per service is the minimum bar
  • Auth must be explicit and stateless
  • Token validation happens in every service

That is the real line between a Django app and a Django microservice.

No comments:

Post a Comment

| Designed by Colorlib