### Signal Performance: Good Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md An example of a performant signal handler that quickly checks if a request path starts with '/api/public/'. ```python # Good - simple check def cors_api_public(sender, request, **kwargs): return request.path.startswith("/api/public/") ``` -------------------------------- ### Django CORS Headers Configuration Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Provides a comprehensive example of configuring django-cors-headers in Django's settings.py and urls.py, along with a browser JavaScript fetch example. ```python # settings.py INSTALLED_APPS = [ "corsheaders", "django.contrib.admin", "django.contrib.auth", # ... other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", # ... other middleware ] CORS_ALLOWED_ORIGINS = [ "https://example.com", "https://app.example.com", ] CORS_ALLOW_HEADERS = [ "accept", "authorization", "content-type", "user-agent", "x-csrftoken", "x-requested-with", "x-custom-header", ] CORS_ALLOW_METHODS = [ "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", ] # urls.py from django.http import JsonResponse def api_endpoint(request): return JsonResponse({"status": "ok"}) # Browser JavaScript # This will include CORS headers in the response fetch("https://api.example.com/api/endpoint", { method: "GET", headers: { "x-custom-header": "value" } }) .then(response => response.json()) .then(data => console.log(data)); ``` -------------------------------- ### Example Django Views for CorsMiddleware Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Provides example synchronous and asynchronous Django views that demonstrate how the CorsMiddleware interacts with them. ```python # For sync views: from django.http import HttpResponse def my_view(request): return HttpResponse("Hello World") # For async views: async def my_async_view(request): return HttpResponse("Hello World") ``` -------------------------------- ### Install django-cors-headers Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Install the package using pip. Ensure you are using the correct Python module execution. ```sh python -m pip install django-cors-headers ``` -------------------------------- ### Complete Django CORS Headers Configuration Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/configuration.md A comprehensive example of django-cors-headers configuration in settings.py, including origin, method, header, and other settings. Demonstrates environment-specific origin configuration. ```python # settings.py from corsheaders.defaults import default_headers, default_methods import re from pathlib import Path DEBUG = False # Set appropriately per environment # ============================================================================ # CORS Configuration # ============================================================================ INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "corsheaders", # Add before other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # Add first "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", # ... other middleware ] # --- Origin Configuration --- if DEBUG: CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://localhost:8000", "http://127.0.0.1:3000", ] else: CORS_ALLOWED_ORIGINS = [ "https://example.com", "https://app.example.com", "https://www.example.com", ] CORS_ALLOWED_ORIGIN_REGEXES = [ r"^https://\w+\.example\.com$", # All subdomains ] # --- Methods Configuration --- CORS_ALLOW_METHODS = ( *default_methods, ) # --- Headers Configuration --- CORS_ALLOW_HEADERS = ( *default_headers, "x-api-version", "x-api-key", ) CORS_EXPOSE_HEADERS = [ "x-total-count", "x-page-number", ] # --- Other Configuration --- CORS_ALLOW_CREDENTIALS = True CORS_PREFLIGHT_MAX_AGE = 3600 CORS_URLS_REGEX = r"^/api/.*$" CORS_ALLOW_PRIVATE_NETWORK = False # --- Session Configuration (when using CORS_ALLOW_CREDENTIALS) --- SESSION_COOKIE_SAMESITE = "None" SESSION_COOKIE_SECURE = True CSRF_TRUSTED_ORIGINS = [ "https://app.example.com", "https://example.com", ] ``` -------------------------------- ### Example Invalid CORS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/app-config.md Shows examples of incorrectly configured CORS settings that will trigger system check errors, highlighting common mistakes. ```python # settings.py # INVALID - will trigger system check errors CORS_ALLOWED_ORIGINS = "https://example.com" # E006: must be sequence CORS_ALLOW_HEADERS = ("accept", 123) # E001: must be all strings CORS_ALLOW_CREDENTIALS = "yes" # E003: must be boolean CORS_PREFLIGHT_MAX_AGE = -1 # E004: must be >= 0 CORS_ALLOW_ALL_ORIGINS = "true" # E005: must be boolean ``` -------------------------------- ### Middleware Placement Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md Illustrates the recommended placement of CorsMiddleware in the Django middleware stack. It should be the first middleware listed. ```python MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # 1st - CORS first "django.middleware.security.SecurityMiddleware", # 2nd "django.contrib.sessions.middleware.SessionMiddleware", # 3rd "django.middleware.common.CommonMiddleware", # Must be after CORS "django.middleware.csrf.CsrfViewMiddleware", # ... rest ] ``` -------------------------------- ### Combine Static Configuration with Dynamic Signal Logic Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Use signals to add dynamic CORS logic that complements static configuration. This example allows dynamic access for paths starting with '/api/public/' if the origin is not already in `CORS_ALLOWED_ORIGINS`. ```python # settings.py CORS_ALLOWED_ORIGINS = [ "https://trusted-partner.com", ] # myapp/handlers.py - adds dynamic logic def cors_allow_dynamic(sender, request, **kwargs): # This is checked IF the origin isn't in CORS_ALLOWED_ORIGINS return request.path.startswith("/api/public/") ``` -------------------------------- ### GitHub Actions Workflow for Django Checks Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md An example GitHub Actions workflow that sets up Python, installs dependencies, and runs Django security checks with a failure level of ERROR. This integrates checks into a CI pipeline. ```yaml name: Django Checks on: [push, pull_request] jobs: checks: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.10' - run: pip install django django-cors-headers - run: python manage.py check --tag security --fail-level ERROR ``` -------------------------------- ### Signal Performance: Bad Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md An example of an inefficient signal handler that performs N+1 database queries, which can significantly slow down request processing. ```python # Bad - N+1 database queries def cors_bad(sender, request, **kwargs): origin = request.headers.get("origin") for site in Site.objects.all(): # Slow! if origin == site.origin: return True return False ``` -------------------------------- ### Basic View Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Demonstrates a simple Django view where the CORS middleware automatically adds necessary headers. ```python def api_endpoint(request): response = HttpResponse("API Response") # Middleware automatically adds CORS headers return response ``` -------------------------------- ### Run Django Checks Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Provides examples of how to execute Django's check command. It shows how to run all checks, filter by tag (e.g., security), and use the `--deploy` flag. ```bash # Run all checks python manage.py check # Run only security checks (includes CORS) python manage.py check --tag security # Run checks and deploy checks python manage.py check --deploy # Check fails with non-zero exit code if errors found python manage.py check || echo "Validation failed" ``` -------------------------------- ### Example Valid CORS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/app-config.md Illustrates a correctly configured set of CORS settings in Django's settings.py that will pass system checks. ```python # settings.py # VALID - no errors CORS_ALLOWED_ORIGINS = [ "https://example.com", "https://app.example.com", ] CORS_ALLOW_HEADERS = ["accept", "authorization", "content-type"] CORS_ALLOW_METHODS = ["GET", "POST", "PUT"] CORS_ALLOW_CREDENTIALS = True CORS_PREFLIGHT_MAX_AGE = 86400 ``` -------------------------------- ### Security Headers Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md Example of configuring Django's security headers, which works alongside django-cors-headers. ```python SECURE_SSL_REDIRECT = True SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True ``` -------------------------------- ### Example Output of System Checks Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Illustrates the typical output format when Django CORS system checks identify configuration issues. ```text System check identified some issues: ERRORS: corsheaders.E006: CORS_ALLOWED_ORIGINS should be a sequence of strings. corsheaders.E014: Origin 'https://example.com/api' in CORS_ALLOWED_ORIGINS should not have path System check identified 2 issues. ``` -------------------------------- ### Examples of Sequence[str] Types Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/types.md Illustrates various sequence types (list, tuple) that conform to Sequence[str], used for settings like CORS_ALLOWED_ORIGINS and CORS_ALLOW_HEADERS. ```python # All are Sequence[str] ["https://example.com"] ("https://example.com",) ("header1", "header2", "header3") ``` -------------------------------- ### Allow All Origins for API Endpoints Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Example signal handler that allows all origins to access URLs starting with '/api/'. This is useful for public APIs while maintaining restricted access for other parts of the site. ```python # myapp/handlers.py from corsheaders.signals import check_request_enabled def cors_allow_api_to_everyone(sender, request, **kwargs): return request.path.startswith("/api/") check_request_enabled.connect(cors_allow_api_to_everyone) ``` -------------------------------- ### Migrating CORS_ALLOW_HEADERS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/defaults.md This example demonstrates how to migrate from a hardcoded list of default headers to an extensible configuration using `corsheaders.defaults.default_headers`. This approach simplifies maintenance and automatically includes new defaults in future versions. ```python # Old way (hardcoded) CORS_ALLOW_HEADERS = ( "accept", "authorization", "content-type", "user-agent", "x-csrftoken", "x-requested-with", "x-custom-header", ) # New way (extensible) from corsheaders.defaults import default_headers CORS_ALLOW_HEADERS = ( *default_headers, "x-custom-header", ) ``` -------------------------------- ### Invalid CORS_ALLOW_HEADERS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of incorrect configurations for CORS_ALLOW_HEADERS, which should be a sequence of strings. ```python # Not a sequence CORS_ALLOW_HEADERS = "accept,authorization,content-type" ``` ```python # Contains non-strings CORS_ALLOW_HEADERS = ["accept", 123, "authorization"] ``` ```python # Not a sequence type CORS_ALLOW_HEADERS = {"accept", "authorization"} # set, not sequence ``` -------------------------------- ### Inspect Installed Version Source: https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst Use this method to check the installed version of django-cors-headers after the __version__ attribute was removed from the package. ```python importlib.metadata.version("django-cors-headers") ``` -------------------------------- ### API Reference Guides Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/COMPLETION_SUMMARY.txt The API reference guides detail the public API of django-cors-headers, including classes, functions, signals, and configuration options. These guides are generated from the source code and provide comprehensive information for developers. ```APIDOC ## API Reference Guides This section outlines the API documentation generated for the django-cors-headers library. ### Documentation Structure The API reference is organized into several markdown files, each covering a specific aspect of the library's public interface: - **`api-reference/cors-middleware.md`**: Details the `CorsMiddleware` class, including its 14 public methods and properties. - **`api-reference/settings-class.md`**: Documents the `Settings` proxy class, covering its 10 configuration properties. - **`api-reference/signals.md`**: Describes the signal system, including the `check_request_enabled` signal. - **`api-reference/checks.md`**: Covers validation utilities like `check_settings()` and `is_sequence()`. - **`api-reference/app-config.md`**: Documents the `CorsHeadersAppConfig` class, specifically its `ready()` method. - **`api-reference/defaults.md`**: Lists and explains the documented constants and default values. ### Features Each API document includes: - Clear hierarchy with markdown headings. - Full method/function signatures. - Parameter tables (name, type, required, default, description). - Return type documentation. - Error conditions (where applicable). - Complete code examples. - Source file references (path + line numbers). - Cross-references to related documentation. ### Configuration Options The documentation covers 10 configuration options, including: - `CORS_ALLOWED_ORIGINS` - `CORS_ALLOWED_ORIGIN_REGEXES` - `CORS_ALLOW_ALL_ORIGINS` - `CORS_ALLOW_METHODS` - `CORS_ALLOW_HEADERS` - `CORS_EXPOSE_HEADERS` - `CORS_ALLOW_CREDENTIALS` - `CORS_ALLOW_PRIVATE_NETWORK` - `CORS_PREFLIGHT_MAX_AGE` - `CORS_URLS_REGEX` These options are documented with type specifications, default values, validation rules, integration notes, and environment-specific examples. ``` -------------------------------- ### Configuring CORS_ALLOWED_ORIGIN_REGEXES in Django Settings Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Provides an example of setting up regular expressions in Django settings to match allowed origins, useful for dynamic subdomains or pattern-based matching. ```python # In Django settings CORS_ALLOWED_ORIGIN_REGEXES = [ r"^https://\w+\.example\.com$", r"^https://[a-z0-9]+\.staging\.example\.com$", re.compile(r"^http://localhost:\d+$"), ] ``` -------------------------------- ### Django AppConfig for Signal Connection Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Example of a Django AppConfig to ensure signal handlers are connected when the application is ready. This is typically placed in myapp/__init__.py and myapp/apps.py. ```python # myapp/__init__.py defa ``` ```python # myapp/apps.py from django.apps import AppConfig class MyAppConfig(AppConfig): name = "myapp" def ready(self): # Makes sure all signal handlers are connected from myapp import handlers # noqa ``` -------------------------------- ### Invalid CORS_PREFLIGHT_MAX_AGE Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of invalid configurations for CORS_PREFLIGHT_MAX_AGE, which must be a non-negative integer. ```python # String instead of int CORS_PREFLIGHT_MAX_AGE = "3600" ``` ```python # Negative value CORS_PREFLIGHT_MAX_AGE = -1 ``` ```python # Float CORS_PREFLIGHT_MAX_AGE = 3600.5 ``` ```python # None or other types CORS_PREFLIGHT_MAX_AGE = None ``` -------------------------------- ### Dynamic CORS Configuration Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Demonstrates how to conditionally override CORS settings based on environment variables or other dynamic conditions within Django's settings. ```python # Example with dynamic configuration from django.conf import settings if hasattr(settings, "CORS_ALLOW_CREDENTIALS"): # Override credentials based on environment CORS_ALLOW_CREDENTIALS = True ``` -------------------------------- ### Correct CORS_URLS_REGEX Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Provides examples of valid CORS_URLS_REGEX configurations using a string, a compiled regex pattern, or the default pattern to match all URLs. ```python import re # Correct - string CORS_URLS_REGEX = r"^/api/.*$" ``` ```python # Compiled pattern CORS_URLS_REGEX = re.compile(r"^/api/.*$") ``` ```python # Match all (default) CORS_URLS_REGEX = r"^.*$" ``` -------------------------------- ### Basic CORS Configuration Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md Configure allowed origins for CORS requests in your Django settings. At least one origin setting is required. ```python # settings.py INSTALLED_APPS = [ "corsheaders", "django.contrib.admin", # ... other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", # ... other middleware ] # Required: at least one origin setting CORS_ALLOWED_ORIGINS = [ "https://example.com", "https://app.example.com", ] ``` -------------------------------- ### Invalid CORS_ALLOW_ALL_ORIGINS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of invalid configurations for CORS_ALLOW_ALL_ORIGINS (or legacy CORS_ORIGIN_ALLOW_ALL), which must be a boolean. ```python # String instead of bool CORS_ALLOW_ALL_ORIGINS = "true" ``` ```python # Integer CORS_ALLOW_ALL_ORIGINS = 1 ``` ```python # Other type CORS_ALLOW_ALL_ORIGINS = "yes" ``` -------------------------------- ### Allow CORS for Specific URL Patterns Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md This example demonstrates how to allow CORS for all origins on specific URL patterns, such as public API endpoints. The handler checks if the request path starts with '/api/'. ```python from corsheaders.signals import check_request_enabled def cors_allow_api_to_everyone(sender, request, **kwargs): """Allow CORS for all origins on /api/ endpoints""" return request.path.startswith("/api/") check_request_enabled.connect(cors_allow_api_to_everyone) ``` -------------------------------- ### Invalid CORS_ALLOW_METHODS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of invalid configurations for CORS_ALLOW_METHODS, which must be a sequence of strings representing HTTP methods. ```python # Not a sequence CORS_ALLOW_METHODS = "GET,POST,PUT" ``` ```python # Contains non-strings CORS_ALLOW_METHODS = ["GET", "POST", 123] ``` ```python # Wrong type CORS_ALLOW_METHODS = {"GET", "POST"} # set ``` -------------------------------- ### Invalid CORS_ALLOWED_ORIGINS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of invalid configurations for CORS_ALLOWED_ORIGINS (or legacy CORS_ORIGIN_WHITELIST), which must be a sequence of strings. ```python # String instead of sequence CORS_ALLOWED_ORIGINS = "https://example.com" ``` ```python # Contains non-strings CORS_ALLOWED_ORIGINS = ["https://example.com", 123] ``` ```python # Wrong type CORS_ALLOWED_ORIGINS = {"https://example.com"} # set ``` -------------------------------- ### Invalid CORS_ALLOW_CREDENTIALS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Examples of incorrect configurations for CORS_ALLOW_CREDENTIALS, which must be a boolean value. ```python # Strings instead of bool CORS_ALLOW_CREDENTIALS = "true" CORS_ALLOW_CREDENTIALS = "yes" ``` ```python # Other types CORS_ALLOW_CREDENTIALS = 1 CORS_ALLOW_CREDENTIALS = ["true"] ``` -------------------------------- ### Correct CORS_ALLOWED_ORIGINS Format Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Demonstrates the correct format for origins in CORS_ALLOWED_ORIGINS, requiring both a scheme and a netloc. Includes examples with ports, different schemes, and the special 'null' value. ```python CORS_ALLOWED_ORIGINS = [ "https://example.com", "http://localhost:3000", "https://app.example.com:8443", "http://127.0.0.1:8000", "null", # Special value OK ] ``` -------------------------------- ### Complete CORS Configuration with Defaults Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/defaults.md A comprehensive example of configuring CORS settings in Django's settings.py, utilizing default headers and methods while adding custom origins and other options. ```python # settings.py from corsheaders.defaults import default_headers, default_methods INSTALLED_APPS = [ "corsheaders", # ... other apps ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # ... other middleware ] CORS_ALLOWED_ORIGINS = [ "https://example.com", "https://app.example.com", ] CORS_ALLOW_HEADERS = ( *default_headers, "x-api-key", "x-client-version", ) CORS_ALLOW_METHODS = ( *default_methods, "HEAD", ) CORS_ALLOW_CREDENTIALS = True CORS_PREFLIGHT_MAX_AGE = 3600 ``` -------------------------------- ### Registering CorsHeaders AppConfig Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/app-config.md Shows how to add the corsheaders app to Django's INSTALLED_APPS for automatic registration. This is the standard way to install the app. ```python # settings.py INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", # ... "corsheaders", # Add this # ... ] ``` -------------------------------- ### Configure CORS and CSRF Trusted Origins Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Example showing how to configure CORS allowed origins and CSRF trusted origins to allow cross-site requests to specific domains. ```python CORS_ALLOWED_ORIGINS = [ "https://read-only.example.com", "https://read-and-write.example.com", ] CSRF_TRUSTED_ORIGINS = [ "https://read-and-write.example.com", ] ``` -------------------------------- ### Complete Type-Annotated CORS Configuration and Middleware Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/types.md Provides a comprehensive example of type annotations for a `CORSConfig` class and the middleware signature. This demonstrates how to fully leverage Python's typing system for CORS-related components. ```python from typing import Any from collections.abc import Callable, Awaitable, Sequence from re import Pattern from urllib.parse import SplitResult, urlsplit from django.http import HttpRequest, HttpResponse from django.http.response import HttpResponseBase # Complete type-annotated CORS configuration class CORSConfig: allowed_origins: Sequence[str] allowed_origin_regexes: Sequence[str | Pattern[str]] allow_all_origins: bool allow_methods: Sequence[str] allow_headers: Sequence[str] expose_headers: Sequence[str] allow_credentials: bool allow_private_network: bool preflight_max_age: int urls_regex: str | Pattern[str] # Middleware typed signature def middleware( get_response: Callable[ [HttpRequest], HttpResponseBase | Awaitable[HttpResponseBase] ] ) -> Callable[[HttpRequest], HttpResponseBase | Awaitable[HttpResponseBase]]: def inner(request: HttpRequest) -> HttpResponseBase: return HttpResponse() return inner # Signal handler signature def cors_handler( sender: None, request: HttpRequest, **kwargs: Any ) -> bool: return True ``` -------------------------------- ### Custom CORS Signal Handler Example Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Demonstrates how to connect a custom signal handler to the `check_request_enabled` signal to dynamically control CORS behavior. ```python from corsheaders.signals import check_request_enabled def cors_allow_mysites(sender, request, **kwargs): # Allow CORS for specific paths return request.path.startswith("/api/") check_request_enabled.connect(cors_allow_mysites) ``` -------------------------------- ### Running Django System Checks for CORS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/app-config.md Use the `python manage.py check --deploy` command to identify deployment-ready settings issues related to CORS configuration. This helps catch errors before the application starts. ```bash python manage.py check --deploy # Check deployment-ready settings ``` ```text System check identified some issues: ERRORS: corsheaders.E013: Origin 'https://example.com/api' in CORS_ALLOWED_ORIGINS is missing scheme or netloc HINT: Add a scheme (e.g. https://) or netloc (e.g. example.com). ``` -------------------------------- ### Dynamic Origin List from Database Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md This example shows how to dynamically allow CORS based on origins stored in the database. The handler checks if the requesting origin exists and is active in the `AllowedOrigin` model. ```python from corsheaders.signals import check_request_enabled from myapp.models import AllowedOrigin def cors_allow_from_database(sender, request, **kwargs): """Check if the requesting origin is in the database""" origin = request.headers.get("origin") if not origin: return False return AllowedOrigin.objects.filter( origin=origin, is_active=True ).exists() check_request_enabled.connect(cors_allow_from_database) ``` -------------------------------- ### Environment-Based CORS Rules Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md This example implements CORS rules based on the Django environment settings. It allows CORS for localhost origins only when `settings.DEBUG` is True. ```python from corsheaders.signals import check_request_enabled from django.conf import settings def cors_allow_by_environment(sender, request, **kwargs): """Allow CORS for localhost in development""" if not settings.DEBUG: return False origin = request.headers.get("origin") return origin and origin.startswith("http://localhost") check_request_enabled.connect(cors_allow_by_environment) ``` -------------------------------- ### Example JavaScript Triggering a Preflight Request Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Demonstrates JavaScript code using the Fetch API that automatically triggers a CORS preflight request to a Django API endpoint. ```javascript fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({foo: 'bar'}) }); # Django receives OPTIONS request with access-control-request-method header ``` -------------------------------- ### Accessing CORS_ALLOWED_ORIGIN_REGEXES Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Illustrates how to get the sequence of regular expression patterns used for matching allowed origins. This allows for pattern-based matching. ```python from corsheaders.conf import conf import re regexes = conf.CORS_ALLOWED_ORIGIN_REGEXES # Can contain strings or compiled re.Pattern objects ``` -------------------------------- ### Write Custom CORS Security Checks Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Demonstrates how to implement custom Django checks for CORS security. This example warns if CORS_ALLOW_ALL_ORIGINS is enabled in production or if the number of allowed origins exceeds a threshold. ```python # myapp/checks.py from django.core.checks import Error, register, Tags from corsheaders.checks import is_sequence from corsheaders.conf import conf @register(Tags.security) def check_cors_security(app_configs, **kwargs): errors = [] # Custom check: warn if allow_all_origins in non-debug if conf.CORS_ALLOW_ALL_ORIGINS and not settings.DEBUG: errors.append(Error( "CORS_ALLOW_ALL_ORIGINS should not be True in production", id="myapp.W001", hint="Restrict to specific origins in production" )) # Custom check: warn if too many origins if len(conf.CORS_ALLOWED_ORIGINS) > 50: errors.append(Error( "Too many CORS origins configured", id="myapp.W002", hint="Consider using CORS_ALLOWED_ORIGIN_REGEXES instead" )) return errors ``` -------------------------------- ### Invalid CORS_EXPOSE_HEADERS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Highlights invalid configurations for CORS_EXPOSE_HEADERS, which must be a sequence. Examples include using a string, a single value not in a sequence, or a set. ```python # String instead of sequence CORS_EXPOSE_HEADERS = "x-total-count,x-page-number" ``` ```python # Single value not in sequence CORS_EXPOSE_HEADERS = "x-total-count" ``` ```python # Not a sequence type CORS_EXPOSE_HEADERS = {"x-total-count"} # set ``` -------------------------------- ### Different CORS Rules for Different Paths Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md Apply specific CORS rules to certain paths while using a default for others. This example allows any origin for public API paths. ```python CORS_ALLOWED_ORIGINS = ["https://trusted.example.com"] from corsheaders.signals import check_request_enabled def cors_public_api(sender, request, **kwargs): # Public API endpoints allow any origin return request.path.startswith("/api/public/") check_request_enabled.connect(cors_public_api) ``` -------------------------------- ### Allow Read-Only from Anywhere Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Implement a signal handler to allow GET, HEAD, and OPTIONS requests from any origin, while restricting write operations. Connect this handler to the `check_request_enabled` signal. ```python from corsheaders.signals import check_request_enabled def cors_allow_read_only_from_anywhere(sender, request, **kwargs): """Allow CORS for GET requests from anywhere, but restrict writes""" if request.method in ["GET", "HEAD", "OPTIONS"]: return True # For write operations, let normal CORS config decide return False check_request_enabled.connect(cors_allow_read_only_from_anywhere) ``` -------------------------------- ### Document Signal Handler Intent Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Add clear docstrings to signal handlers to explain their purpose and logic. This example documents a handler that allows CORS for partner API clients. ```python def cors_allow_partners(sender, request, **kwargs): """ Allow CORS for partner API clients. Partner origins are loaded from the database and checked against the request origin. This is cached for 5 minutes to avoid excessive database queries. """ # handler implementation ``` -------------------------------- ### Accessing CORS_PREFLIGHT_MAX_AGE Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Retrieves the maximum age in seconds for caching preflight responses. Set to `0` to omit the `Access-Control-Max-Age` header. The example shows how to get the current setting and how to configure it in Django settings. ```python from corsheaders.conf import conf max_age = conf.CORS_PREFLIGHT_MAX_AGE print(max_age) # 86400 # In Django settings CORS_PREFLIGHT_MAX_AGE = 3600 # 1 hour ``` -------------------------------- ### Accessing CORS_ALLOW_METHODS Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Retrieves the list of allowed HTTP methods for cross-origin requests. This is reported in the `Access-Control-Allow-Methods` preflight response header. The example shows how to get the current settings and how to configure it in Django settings. ```python from corsheaders.conf import conf from corsheaders.defaults import default_methods # Get current settings methods = conf.CORS_ALLOW_METHODS print(methods) # ("DELETE", "GET", "OPTIONS", ...) # In Django settings CORS_ALLOW_METHODS = ( *default_methods, "HEAD", "TRACE", ) ``` -------------------------------- ### Accessing CORS_ALLOW_HEADERS Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Retrieves the list of allowed HTTP headers for cross-origin requests. This is reported in the `Access-Control-Allow-Headers` preflight response header. The example shows how to get the current settings and how to configure it in Django settings. ```python from corsheaders.conf import conf from corsheaders.defaults import default_headers # Get current settings allowed = conf.CORS_ALLOW_HEADERS print(allowed) # ("accept", "authorization", ...) # In Django settings CORS_ALLOW_HEADERS = ( *default_headers, "x-api-key", "x-custom-header", ) ``` -------------------------------- ### Cache Database Results in Signal Handler Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Cache database query results for signal handlers to improve performance. This example caches CORS allowance status for a given origin for 5 minutes. ```python from django.core.cache import cache from corsheaders.signals import check_request_enabled def cors_allow_from_cache(sender, request, **kwargs): origin = request.headers.get("origin") if not origin: return False cache_key = f"cors_allowed:{origin}" allowed = cache.get(cache_key) if allowed is None: allowed = AllowedOrigin.objects.filter( origin=origin, is_active=True ).exists() cache.set(cache_key, allowed, 300) # Cache for 5 minutes return allowed check_request_enabled.connect(cors_allow_from_cache) ``` -------------------------------- ### Configure HTTPS Settings for Production Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/configuration.md In production environments (when DEBUG is False), enforce HTTPS by setting SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE, SECURE_HSTS_SECONDS, and SECURE_HSTS_INCLUDE_SUBDOMAINS. ```python if not DEBUG: SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True ``` -------------------------------- ### Manually Specifying AppConfig Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/app-config.md Demonstrates how to explicitly reference the CorsHeadersAppConfig in Django's INSTALLED_APPS if automatic discovery is not sufficient or desired. ```python # settings.py INSTALLED_APPS = [ "corsheaders.apps.CorsHeadersAppConfig", # ... ] ``` -------------------------------- ### Correct CORS_EXPOSE_HEADERS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Shows the correct way to configure CORS_EXPOSE_HEADERS using a list or tuple, including an empty list if no headers need to be exposed. ```python # Correct CORS_EXPOSE_HEADERS = ["x-total-count", "x-page-number"] ``` ```python CORS_EXPOSE_HEADERS = ("x-total-count", "x-page-number") ``` ```python # Empty if not needed CORS_EXPOSE_HEADERS = [] ``` -------------------------------- ### CorsMiddleware Constructor Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Initializes the CorsMiddleware with a get_response callable. This callable can be either synchronous or asynchronous, and the middleware will adapt accordingly. ```APIDOC ## CorsMiddleware Constructor ### Description Initializes the CorsMiddleware with a `get_response` callable. This callable can be either synchronous or asynchronous, and the middleware will adapt accordingly. ### Parameters #### Path Parameters - **get_response** (Callable) - Required - The next middleware or view callable. Can be either sync or async. ### Return Type None ### Example ```python # Django automatically instantiates middleware # Add to MIDDLEWARE in settings.py: MIDDLEWARE = [ ... "corsheaders.middleware.CorsMiddleware", "django.middleware.common.CommonMiddleware", ... ] ``` ``` -------------------------------- ### Accessing CORS_URLS_REGEX Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Illustrates how to get the regular expression pattern that determines which URL paths CORS headers are applied to. ```python from corsheaders.conf import conf import re pattern = conf.CORS_URLS_REGEX # Default matches all paths ``` -------------------------------- ### Correct CORS_ALLOW_METHODS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Correct ways to configure CORS_ALLOW_METHODS using lists or tuples, or by extending default methods. ```python # Correct CORS_ALLOW_METHODS = ["GET", "POST", "PUT", "DELETE"] ``` ```python # Better - extend defaults from corsheaders.defaults import default_methods CORS_ALLOW_METHODS = (*default_methods, "HEAD") ``` -------------------------------- ### Correct CORS_ALLOW_HEADERS Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Correct ways to configure CORS_ALLOW_HEADERS using lists, tuples, or by extending default headers. ```python # Correct CORS_ALLOW_HEADERS = ["accept", "authorization", "content-type"] CORS_ALLOW_HEADERS = ("accept", "authorization", "content-type") ``` ```python # Better - extend defaults from corsheaders.defaults import default_headers CORS_ALLOW_HEADERS = (*default_headers, "x-custom-header") ``` -------------------------------- ### Invalid CORS Allow Private Network Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md The CORS_ALLOW_PRIVATE_NETWORK setting must be a boolean value. Examples show incorrect string and integer types. ```python # String instead of bool CORS_ALLOW_PRIVATE_NETWORK = "true" # Integer CORS_ALLOW_PRIVATE_NETWORK = 1 # Other type CORS_ALLOW_PRIVATE_NETWORK = "yes" ``` -------------------------------- ### Configuring CORS_EXPOSE_HEADERS in Django Settings Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Demonstrates how to specify additional HTTP headers that should be accessible to the browser via the `Access-Control-Expose-Headers` header in Django settings. ```python # In Django settings CORS_EXPOSE_HEADERS = [ "x-total-count", "x-page-number", "x-custom-response-header", ] ``` -------------------------------- ### Preflight Caching: Shorter Cache Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/README.md Configure a shorter preflight cache duration (1 hour) for quicker updates to headers, at the cost of more frequent preflight requests. ```python # Shorter cache (more requests, quicker updates) CORS_PREFLIGHT_MAX_AGE = 3600 # 1 hour ``` -------------------------------- ### Import Default Headers and Methods Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/defaults.md Import the default headers and methods tuples from the corsheaders.defaults module. This is the initial step for extending or referencing these defaults. ```python from corsheaders.defaults import default_headers, default_methods ``` -------------------------------- ### Correct CORS_ALLOWED_ORIGIN_REGEXES Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Demonstrates correct usage of CORS_ALLOWED_ORIGIN_REGEXES with strings or a mix of strings and compiled regex patterns. ```python import re # Correct - strings CORS_ALLOWED_ORIGIN_REGEXES = [ r"^https://\w+\.example\.com$", ] ``` ```python # Mix of strings and compiled patterns CORS_ALLOWED_ORIGIN_REGEXES = [ r"^https://\w+\.example\.com$", re.compile(r"^http://localhost:\d+$"), ] ``` -------------------------------- ### Example of Invalid Origin Format Error Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Demonstrates a scenario where an origin in `CORS_ALLOWED_ORIGINS` has an invalid format. The output shows the error message indicating an invalid origin URL. ```bash $ python manage.py check System check identified some issues: ERRORS: corsheaders.E006: CORS_ALLOWED_ORIGINS should be a sequence of strings. ``` -------------------------------- ### Correct CORS_ALLOW_CREDENTIALS Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Correct boolean values for the CORS_ALLOW_CREDENTIALS setting. ```python # Correct CORS_ALLOW_CREDENTIALS = True CORS_ALLOW_CREDENTIALS = False ``` -------------------------------- ### Getting Current CORS Configuration Programmatically Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Provides a Python function to retrieve the current CORS configuration values from the `conf` object. This is useful for debugging or dynamic adjustments. ```python from corsheaders.conf import conf # In your Django application code def get_cors_config(): """Get current CORS configuration""" config = { "allow_all": conf.CORS_ALLOW_ALL_ORIGINS, "allowed_origins": list(conf.CORS_ALLOWED_ORIGINS), "allowed_methods": list(conf.CORS_ALLOW_METHODS), "allowed_headers": list(conf.CORS_ALLOW_HEADERS), "expose_headers": list(conf.CORS_EXPOSE_HEADERS), "allow_credentials": conf.CORS_ALLOW_CREDENTIALS, "max_age": conf.CORS_PREFLIGHT_MAX_AGE, "urls_regex": conf.CORS_URLS_REGEX, } return config ``` -------------------------------- ### Allowed Methods Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Define the list of HTTP verbs allowed for cross-site requests. Defaults to a standard set of methods. ```python CORS_ALLOW_METHODS = ( "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT", ) ``` -------------------------------- ### Middleware Configuration and Default Fallbacks Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/defaults.md Illustrates how the CORS middleware uses configured settings, falling back to defaults if specific settings are not provided. Shows the relationship between `conf.CORS_ALLOW_HEADERS` and `default_headers`. ```python from corsheaders.conf import conf from corsheaders.defaults import default_headers, default_methods # These are equivalent: conf.CORS_ALLOW_HEADERS # Uses default_headers as fallback # vs default_headers # Raw default value ``` -------------------------------- ### Multiple CORS Handlers via AppConfig Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Demonstrates how to connect multiple custom CORS signal handlers within a Django application's `AppConfig.ready()` method. This allows for a layered approach to CORS logic. ```python # myapp/apps.py from django.apps import AppConfig class MyAppConfig(AppConfig): name = "myapp" verbose_name = "My Application" def ready(self): from corsheaders.signals import check_request_enabled from myapp.handlers import ( cors_allow_api, cors_allow_dev_localhost, cors_allow_from_config ) # Connect multiple handlers check_request_enabled.connect(cors_allow_api) check_request_enabled.connect(cors_allow_dev_localhost) check_request_enabled.connect(cors_allow_from_config) ``` ```python # myapp/handlers.py def cors_allow_api(sender, request, **kwargs): """Public API endpoints""" return request.path.startswith("/api/v1/public/") def cors_allow_dev_localhost(sender, request, **kwargs): """Development localhost access""" from django.conf import settings if not settings.DEBUG: return False origin = request.headers.get("origin") return origin in ["http://localhost:3000", "http://localhost:8000"] ``` ```python def cors_allow_from_config(sender, request, **kwargs): """Check against custom configuration""" from django.conf import settings origin = request.headers.get("origin") if hasattr(settings, "CORS_CUSTOM_ALLOWED_ORIGINS"): return origin in settings.CORS_CUSTOM_ALLOWED_ORIGINS return False ``` -------------------------------- ### Subdomain-Based CORS Logic Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md This example allows CORS for subdomains of trusted domains. It parses the origin URL and checks if the network location ends with a trusted domain or is the trusted domain itself. ```python from corsheaders.signals import check_request_enabled from urllib.parse import urlsplit def cors_allow_trusted_subdomains(sender, request, **kwargs): """Allow CORS for subdomains of trusted domains""" origin = request.headers.get("origin") if not origin: return False url = urlsplit(origin) netloc = url.netloc.lower() # Allow any subdomain of example.com if netloc.endswith(".example.com") or netloc == "example.com": return True return False check_request_enabled.connect(cors_allow_trusted_subdomains) ``` -------------------------------- ### Connect Signal Handler via AppConfig Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/signals.md Connects a custom CORS handler using Django's AppConfig `ready` method. This is the recommended approach to avoid circular imports and ensure proper signal registration. ```python # myapp/apps.py from django.apps import AppConfig class MyAppConfig(AppConfig): name = "myapp" def ready(self): # Import here to avoid circular imports from myapp.handlers import cors_allow_mysites from corsheaders.signals import check_request_enabled check_request_enabled.connect(cors_allow_mysites) # myapp/__init__.py default_app_config = "myapp.apps.MyAppConfig" # myapp/handlers.py def cors_allow_mysites(sender, request, **kwargs): return MySite.objects.filter(host=request.headers["origin"]).exists() ``` -------------------------------- ### Example Error from corsheaders Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/types.md Shows how a `django.core.checks.Error` is constructed for a specific CORS configuration issue, such as an incorrectly typed CORS_ALLOW_HEADERS setting. This is used within Django's system check framework. ```python Error( "CORS_ALLOW_HEADERS should be a sequence of strings.", id="corsheaders.E001" ) ``` -------------------------------- ### Allow All Origins Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Set to True to allow all origins. Use with caution as this can be a security risk. Other origin restriction settings will be ignored. ```python CORS_ALLOW_ALL_ORIGINS = True ``` -------------------------------- ### Typed Settings Properties Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/types.md Demonstrates how settings properties are typed for static analysis tools like mypy. These types reflect the expected data structures for CORS configuration. ```python from corsheaders.conf import conf # These are all properly typed for mypy/type checkers origins: list[str] | tuple[str] = conf.CORS_ALLOWED_ORIGINS methods: Sequence[str] = conf.CORS_ALLOW_METHODS headers: Sequence[str] = conf.CORS_ALLOW_HEADERS allow_credentials: bool = conf.CORS_ALLOW_CREDENTIALS max_age: int = conf.CORS_PREFLIGHT_MAX_AGE ``` -------------------------------- ### Correct CORS_PREFLIGHT_MAX_AGE Configurations Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Correct non-negative integer values for CORS_PREFLIGHT_MAX_AGE, representing cache duration in seconds. ```python # Correct - 1 hour CORS_PREFLIGHT_MAX_AGE = 3600 ``` ```python # 24 hours CORS_PREFLIGHT_MAX_AGE = 86400 ``` ```python # No cache header CORS_PREFLIGHT_MAX_AGE = 0 ``` -------------------------------- ### Example of Type Error in Origins Setting Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Illustrates a common configuration error where `CORS_ALLOWED_ORIGINS` is provided as a string instead of a list or sequence. The output shows the resulting error message from the Django check. ```python # settings.py CORS_ALLOWED_ORIGINS = "https://example.com" # String instead of list ``` -------------------------------- ### Extending Default Allowed Methods Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Extend the default list of allowed HTTP methods by importing default_methods and adding custom ones. ```python from corsheaders.defaults import default_methods CORS_ALLOW_METHODS = ( *default_methods, "POKE", ) ``` -------------------------------- ### Accessing CORS_ALLOW_CREDENTIALS Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Checks if credentials (cookies, HTTP authentication) are allowed in cross-origin requests. If `True`, the `Access-Control-Allow-Credentials: true` header is added. The example shows how to check the setting and how to configure it in Django settings. ```python from corsheaders.conf import conf if conf.CORS_ALLOW_CREDENTIALS: # Credentials are allowed pass # In Django settings CORS_ALLOW_CREDENTIALS = True ``` -------------------------------- ### Usage of urlsplit in Middleware Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/types.md Shows how to use urlsplit to parse an origin URL string into its components like scheme, netloc, and path. This is used within the middleware logic. ```python from urllib.parse import urlsplit url = urlsplit(origin) # origin is "https://example.com:443/path" # url.scheme == "https" # url.netloc == "example.com:443" ``` -------------------------------- ### Accessing CORS_ALLOW_PRIVATE_NETWORK Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/settings-class.md Checks if requests from public networks to private IPs are allowed. If `True`, the `access-control-allow-private-network: true` header is included in the response when appropriate. The example shows how to check the setting and how to configure it in Django settings. ```python from corsheaders.conf import conf if conf.CORS_ALLOW_PRIVATE_NETWORK: # Private network requests are allowed pass # In Django settings CORS_ALLOW_PRIVATE_NETWORK = True ``` -------------------------------- ### Run Django CORS Checks Programmatically Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/checks.md Demonstrates how to programmatically run CORS system checks and iterate through any reported errors. ```python from corsheaders.checks import check_settings # Run checks programmatically errors = check_settings() for error in errors: print(f"{error.id}: {error.msg}") ``` -------------------------------- ### Custom CORS Request Check Handler Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Example of a custom signal handler to conditionally allow CORS requests based on a model lookup. This handler checks if the request's origin exists in the MySite model. ```python # myapp/handlers.py from corsheaders.signals import check_request_enabled from myapp.models import MySite def cors_allow_mysites(sender, request, **kwargs): return MySite.objects.filter(host=request.headers["origin"]).exists() check_request_enabled.connect(cors_allow_mysites) ``` -------------------------------- ### CorsMiddleware check_preflight Method Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/api-reference/cors-middleware.md Handles CORS preflight requests by checking for the 'OPTIONS' method and the 'access-control-request-method' header. Returns an empty 200 OK response if it's a valid preflight. ```python def check_preflight(self, request: HttpRequest) -> HttpResponseBase | None: ``` -------------------------------- ### Invalid CORS_ALLOWED_ORIGINS Format Source: https://github.com/adamchainz/django-cors-headers/blob/main/_autodocs/errors.md Identifies invalid origin formats in CORS_ALLOWED_ORIGINS, which must include both a scheme (http/https) and a netloc (hostname). Examples include missing schemes, missing netlocs, relative paths, or hostnames without schemes. ```python CORS_ALLOWED_ORIGINS = [ "example.com", # Missing scheme "https://", # Missing netloc "/api", # Relative path "localhost:3000", # Missing scheme ] ``` -------------------------------- ### Exposed Headers Configuration Source: https://github.com/adamchainz/django-cors-headers/blob/main/README.rst Define a list of extra HTTP headers to expose to the browser, in addition to the default safelisted headers. Defaults to an empty list. ```python CORS_EXPOSE_HEADERS = [] ```