feat(multitenancy): Add TenantHeaderMiddleware to support centralized API with tenant switching
- Implemented TenantHeaderMiddleware to switch the database tenant schema based on the 'X-Business-Subdomain' request header. - This allows API requests directed to the centralized 'api' subdomain (e.g., api.lvh.me) to correctly access tenant-specific data when the header is present. - Registered the middleware in multitenancy settings after TenantMainMiddleware.
This commit is contained in:
@@ -94,6 +94,7 @@ MIDDLEWARE = [
|
||||
|
||||
# 1. Tenant resolution
|
||||
'django_tenants.middleware.main.TenantMainMiddleware',
|
||||
'core.middleware.TenantHeaderMiddleware', # Support tenant switching via header
|
||||
|
||||
# 2. Security middleware
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
|
||||
@@ -8,11 +8,35 @@ import json
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.utils import timezone
|
||||
from django.db import connection
|
||||
from django_tenants.utils import get_tenant_model
|
||||
|
||||
logger = logging.getLogger('smoothschedule.security.masquerade')
|
||||
sandbox_logger = logging.getLogger('smoothschedule.sandbox')
|
||||
|
||||
|
||||
class TenantHeaderMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
Middleware to switch tenant based on 'X-Business-Subdomain' header.
|
||||
Allows centralized API domain (e.g., api.smoothschedule.com) to serve tenant-specific data.
|
||||
Must be placed AFTER TenantMainMiddleware.
|
||||
"""
|
||||
def process_request(self, request):
|
||||
# Check for header
|
||||
subdomain = request.META.get('HTTP_X_BUSINESS_SUBDOMAIN')
|
||||
if subdomain:
|
||||
Tenant = get_tenant_model()
|
||||
try:
|
||||
tenant = Tenant.objects.get(schema_name=subdomain)
|
||||
# Only switch if different from current tenant (which might be 'public')
|
||||
if request.tenant.schema_name != tenant.schema_name:
|
||||
request.tenant = tenant
|
||||
connection.set_tenant(request.tenant)
|
||||
# sandbox_logger.debug(f"Switched to tenant '{subdomain}' via header")
|
||||
except Tenant.DoesNotExist:
|
||||
# Invalid subdomain in header - ignore or could raise 400
|
||||
pass
|
||||
|
||||
|
||||
class SandboxModeMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
Middleware to switch between live and sandbox schemas based on:
|
||||
|
||||
Reference in New Issue
Block a user