Skip to content

Middleware

De volgorde van middleware in app.py is belangrijk, omdat elke middleware de request en response kan beïnvloeden voordat deze naar de volgende laag gaat. Hieronder vind je de actuele chain:

VolgordeMiddlewareDoel & Beschrijving
1error_handling_middlewareVangt alle exceptions af en zorgt voor consistente foutafhandeling en logging.
2auth_middlewareHandelt authenticatie, autorisatie en header-validatie af voor beveiligde routes.

Middleware registratie in app.py:

@app.middleware('http')
def error_middleware(event, get_response):
return error_handling_middleware(event, get_response)
@app.middleware('http')
def authentication_middleware(event, get_response):
return auth_middleware(event, get_response)

CORS configuratie:

CORS headers worden geconfigureerd via cors_config in route decorators:

@app.route('/v1/{tenant_id}/users', methods=['GET'], cors=cors_config)

Let op: De volgorde waarin deze decorators in de code staan, bepaalt de volgorde van uitvoering. De eerste decorator wordt als eerste aangeroepen bij een request.


De error handling middleware vangt alle onverwachte fouten op en zorgt voor consistente foutresponses door de hele applicatie. Het onderschept exceptions en converteert ze naar gestandaardiseerde HTTP responses. De middleware genereert ook een request_id voor request tracking en logt alle errors met gestructureerde logging.

  • Request ID generatie: Elke request krijgt een unieke request_id voor tracking
  • Exception mapping: Automatische mapping van exceptions naar gestandaardiseerde error responses
  • Gestructureerde logging: Alle errors worden gelogd met ERROR event type en action field
  • Response duration tracking: Meet en logt de duur van requests
  • Geen specifieke vereisten - de middleware handelt automatisch alle exceptions af

Alle foutresponses volgen een consistent formaat:

400 Bad Request - Validation failed

{
"status": 400,
"message": "Bad Request - Validation failed",
"error_type": "validation_error",
"details": [
{
"field": "email",
"message": "field required"
}
],
"request_id": "abc123",
"timestamp": "2024-01-15T10:30:00Z"
}
  • Separation of Concerns: Centrale foutafhandeling gescheiden van business logic
  • Consistency: Uniforme foutresponses door de hele applicatie
  • Scalability: Eenvoudig nieuwe error types toevoegen via ErrorHandler
  • Maintainability: Centrale plek voor alle foutafhandeling logica
  • Transferability: Herbruikbare error handling patterns
  • Monitoring: Gestructureerde logging voor operationele inzichten

CORS (Cross-Origin Resource Sharing) headers worden geconfigureerd via cors_config in route decorators. De configuratie wordt bepaald op basis van de deployment stage.

Local stage:

  • http://localhost:4321 - Lokale development

Dev stage:

  • http://localhost:4321 - Lokale development
  • https://vemap-frontend.netlify.app - Development frontend
  • https://vemap.nl - Productie domein
  • https://www.vemap.nl - Productie domein met www

Production stage:

  • https://vemap.nl - Productie domein
  • https://www.vemap.nl - Productie domein met www

CORS wordt geconfigureerd via get_cors_config() in cors_utils.py en toegepast op routes:

from chalicelib.utils.cors_utils import get_cors_config
cors_config = get_cors_config(stage)
@app.route('/v1/{tenant_id}/users', methods=['GET'], cors=cors_config)
  • authorization
  • content-type
  • x-user-id
  • x-user-role
  • Separation of Concerns: CORS logica gescheiden van business logic
  • Consistency: Uniforme CORS handling voor alle endpoints
  • Scalability: Eenvoudig nieuwe origins toevoegen
  • Maintainability: Centrale CORS configuratie
  • Security: Origin whitelisting voorkomt CSRF aanvallen

De authenticatie middleware handelt authenticatie en autorisatie af voor alle API endpoints. Het verwerkt verschillende authenticatie flows en valideert vereiste headers voor beveiligde routes. Voor beveiligde routes gebruikt de middleware cookies voor access tokens in plaats van Authorization headers.

Succes requirements:

  • Geldige Basic Authentication header
  • Gebruikersnaam en wachtwoord moeten aanwezig zijn

Foutafhandeling:

401 Unauthorized - No username or password provided

Succes requirements:

  • Geldige Bearer token in Authorization header
  • Token moet correct geformatteerd zijn
  • x-user-id header moet aanwezig zijn

Foutafhandeling:

401 Missing or invalid Authorization header

Succes requirements:

  • Access token in cookie (vereist)
  • Token moet geldig zijn en correct gevalideerd worden
  • tenant_id in URI parameters (vereist)
  • x-user-role header (vereist)
  • x-user-id header (optioneel, wordt uit token gehaald indien niet aanwezig)

Token validatie:

  • Access token wordt geëxtraheerd uit cookies
  • Token wordt gevalideerd via JWT parsing
  • User ID uit token wordt vergeleken met header user ID (indien aanwezig)
  • Token moet geldig zijn en niet verlopen

Foutafhandeling:

401 Missing access token in cookie

401 Invalid access token

401 User ID mismatch between token and header

Refresh Token Flow (/v1/authentication/refresh)

Section titled “Refresh Token Flow (/v1/authentication/refresh)”

Succes requirements:

  • Refresh token in cookie

Foutafhandeling:

401 Missing refresh token

Challenge Flow (/v1/authentication/challenge)

Section titled “Challenge Flow (/v1/authentication/challenge)”

Succes requirements:

  • Geldige Bearer token in Authorization header (session token)

Foutafhandeling:

401 Missing or invalid Authorization header

Forgot Password Flow (/v1/authentication/forgot-password)

Section titled “Forgot Password Flow (/v1/authentication/forgot-password)”

Succes requirements:

  • Email adres in request body

Foutafhandeling:

  • Validatiefouten worden afgehandeld door error handling middleware

Reset Password Flow (/v1/authentication/reset-password)

Section titled “Reset Password Flow (/v1/authentication/reset-password)”

Succes requirements:

  • Email adres in request body
  • Confirmation code in request body
  • Nieuw wachtwoord in request body

Foutafhandeling:

  • Validatiefouten worden afgehandeld door error handling middleware

De volgende paden worden als publiek beschouwd en omzeilen authenticatie validatie:

  • /health
  • /v1/authentication/login
  • /v1/authentication/logout
  • /v1/authentication/refresh
  • /v1/authentication/challenge
  • /v1/authentication/forgot-password
  • /v1/authentication/reset-password
  • Separation of Concerns: Authenticatie logica gescheiden van business logic
  • Consistency: Uniforme authenticatie handling voor alle endpoints
  • Scalability: Eenvoudig nieuwe authenticatie flows toevoegen
  • Maintainability: Centrale authenticatie configuratie
  • Transferability: Herbruikbare authenticatie patterns
  • Security: Gedetailleerde logging voor beveiligingsmonitoring en request tracing via request IDs

Decorators bieden een declaratieve manier om cross-cutting concerns toe te voegen aan functies en routes. Ze worden gebruikt voor role-based access control, performance monitoring en andere functionaliteiten die op meerdere plekken nodig zijn.

Wat moet je aanleveren voor succes:

  • Functie moet aangeroepen worden met geldige authenticatie context
  • Gebruiker moet een van de toegestane rollen hebben
  • Vereiste rollen worden als parameters meegegeven aan de decorator

Wat krijg je terug bij geen succes:

403 Forbidden - Access denied

{
"status": 403,
"message": "Forbidden - Access denied",
"error_type": "authorization_error",
"details": "Insufficient permissions to access this resource",
"request_id": "abc123def456",
"timestamp": "2024-01-15T10:30:00Z"
}

Logging:

De decorator logt autorisatie events:

  • Bij succes: SUCCESS event met action: "authorize_request"
  • Bij falen: AUTH_FAILURE_NO_ROLES of AUTH_FAILURE_INSUFFICIENT_ROLES security events

Gebruik:

@app.route('/v1/{tenant_id}/users', methods=['POST'], cors=cors_config)
@require_roles('ROLE_ADMIN', 'ROLE_ORGANISATION', 'ROLE_MANAGER')
def create_user(tenant_id: str) -> Response:
# Functie logica hier
pass

Wat moet je aanleveren voor succes:

  • Geen specifieke vereisten - de decorator meet automatisch alle functie uitvoeringen

Wat krijg je terug bij geen succes:

  • Geen foutresponses - de decorator faalt nooit
  • Alle functie uitvoeringen worden gelogd met uitvoeringstijd in milliseconden

Gebruik:

@timer("create_user_controller")
def create_user(self, validated_request: CreateUserRequest) -> Response:
# Functie logica hier
pass
# Of zonder label (gebruikt functienaam)
@timer()
def update_project(self, validated_request: UpdateProjectRequest) -> Response:
# Functie logica hier
pass
  • Separation of Concerns: Cross-cutting concerns gescheiden van business logic
  • Consistency: Uniforme role-based access control en performance monitoring
  • Scalability: Eenvoudig nieuwe decorators toevoegen voor andere concerns
  • Maintainability: Centrale plek voor alle decorator logica
  • Transferability: Herbruikbare decorator patterns
  • Monitoring: Gestructureerde logging voor autorisatie en performance tracking