Tenant Specific Authentication
Overview
The tenant engine workflow in this application is designed to handle multi-tenancy, ensuring that each tenant's data is isolated and that the correct database session is used for each authenticated user. This document explains how the tenant engine is integrated with the authentication process and how it manages database sessions.
Key Components
- Tenant Identification
- Database Session Management
- Repository and Service Initialization
Detailed Workflow
1. Tenant Identification
The tenant is identified during the authentication process:
- For user authentication:
- The user's account is retrieved or created during token validation.
- The account contains the tenant information.
- For machine (service client) authentication:
- The account is fetched based on the
client_idin the token. - The tenant is derived from this account.
2. Database Session Management
Once the tenant is identified, the appropriate database session is created:
def get_tenant_session(
user_with_account: UserWithAccount = Depends(validate_token),
) -> Session:
tenant_id = user_with_account.account.tenant
db_generator = get_tenant_db(tenant_id)
db = next(db_generator)
try:
yield db
finally:
db_generator.close()
This function:
- Takes a
UserWithAccountobject, which is obtained from the token validation process. - Extracts the tenant ID from the user's account.
- Uses
get_tenant_db(tenant_id)to create a database session specific to that tenant. - Yields the session for use in the request.
- Ensures the session is closed after the request is completed.
3. Repository and Service Initialization
The tenant-specific database session is then used to initialize repositories and services:
def get_repository(repo_class):
def _get_repo(db: Session = Depends(get_tenant_session)):
return repo_class(db)
return _get_repo
def get_service(service_class, repo_class):
def _get_service(db: Session = Depends(get_tenant_session)):
repo = repo_class(db)
return service_class(repo)
return _get_service
These functions:
- Use dependency injection to get the tenant-specific database session.
- Create repositories and services with the correct database session.
- Ensure that all database operations are performed in the context of the correct tenant.
Integration with FastAPI
The tenant engine is seamlessly integrated with FastAPI's dependency injection system:
- The
validate_tokendependency identifies the user and their associated tenant. - The
get_tenant_sessiondependency uses this information to create the appropriate database session. - Repository and service dependencies use
get_tenant_sessionto ensure they operate on the correct tenant's data.
This tenant engine workflow ensures that your application can securely and efficiently handle multiple tenants, providing a robust foundation for multi-tenant applications.