django-cors-headers Documentation

repository·main·Indexed 26 days ago

https://github.com/adamchainz/django-cors-headers

A Django application that adds Cross-Origin Resource Sharing (CORS) headers to responses, allowing in-browser requests to a Django application from different origins. Includes configuration for allowed origins via CORS_ALLOWED_ORIGINS, CORS_ALLOWED_ORIGIN_REGEXES, and CORS_ALLOW_ALL_ORIGINS, as well as settings for allowed methods, headers, and credentials. Supports custom logic via the check_request_enabled signal and provides built-in system checks for configuration validation.

Tokens
2.8K
Snippets
8
Records
14
Agent score
91%

What's inside django-cors-headers

  1. Integrate CORS with Django CSRF protection

    main

    CORS and CSRF are separate mechanisms. django-cors-headers does not automatically exempt sites from Django's Referer checking on secure requests. To allow cross-site requests that include CSRF protection, you must also add the allowed origins to Django's CSRF_TRUSTED_ORIGINS setting.

    Example configuration:

    CORS_ALLOWED_ORIGINS = [
        "https://read-only.example.com",
        "https://read-and-write.example.com",
    ]
    
    CSRF_TRUSTED_ORIGINS = [
        "https://read-and-write.example.com",
    ]
  2. Configure django-cors-headers in Django

    main

    To use django-cors-headers, you must add it to your INSTALLED_APPS and add CorsMiddleware to your MIDDLEWARE setting.

    Important: CorsMiddleware should be placed as high as possible in the MIDDLEWARE list, specifically before any middleware that generates responses (like django.middleware.common.CommonMiddleware or WhiteNoiseMiddleware).

    INSTALLED_APPS = [
        ...,
        "corsheaders",
        ...,
    ]
    
    MIDDLEWARE = [
        ...,
        "corsheaders.middleware.CorsMiddleware",
        "django.middleware.common.CommonMiddleware",
        ...,
    ]
  3. Connect CORS signal handlers in Django AppConfig

    main

    To ensure signal handlers are properly connected when Django starts, import your handlers within the ready() method of your AppConfig class.

    # 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
  4. Configure allowed origins

    main

    You must set at least one of the following three settings to control which origins are authorized to make cross-site HTTP requests:

    1. CORS_ALLOWED_ORIGINS: A list of specific origins (URI scheme + hostname + port). Supports special values 'null' and 'file://'.
    2. CORS_ALLOWED_ORIGIN_REGEXES: A list of regexes to match origins. Useful for large numbers of subdomains.
    3. CORS_ALLOW_ALL_ORIGINS: A boolean. If True, all origins are allowed. Warning: This can be dangerous as it allows any website to make requests to your server.
    # Using specific origins
    CORS_ALLOWED_ORIGINS = [
        "https://example.com",
        "https://sub.example.com",
        "http://localhost:8080",
        "http://127.0.0.1:9000",
    ]
    
    # Using regexes
    CORS_ALLOWED_ORIGIN_REGEXES = [
        r"^https://\w+\.example\.com$",
    ]
    
    # Allowing everything (dangerous)
    CORS_ALLOW_ALL_ORIGINS = True
  5. Configure CORS credentials and private network access

    main

    Settings for handling cookies and private network requests.

    • CORS_ALLOW_CREDENTIALS: If True, cookies will be allowed in cross-site requests (sets Access-Control-Allow-Credentials). Defaults to False. Note: If using Django sessions, you may need to set SESSION_COOKIE_SAMESITE = 'None' in your Django settings.
    • CORS_ALLOW_PRIVATE_NETWORK: If True, allows requests from sites on "public" IPs to this server on a "private" IP. This handles the access-control-request-private-network header.
  6. Allow specific URL paths to all origins using signals

    main

    You can use the check_request_enabled signal to allow all origins to access a specific subset of URLs (e.g., an API) while maintaining strict CORS_ALLOWED_ORIGINS for the rest of the application.

    1. Define your trusted origins in CORS_ALLOWED_ORIGINS for general access.
    2. Create a signal handler that returns True if the request.path matches your target subset.
    # 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)
  7. Use the check_request_enabled signal for custom CORS logic

    main

    If standard configuration is insufficient, you can use the check_request_enabled Django signal to implement custom logic for allowing requests. If any handler connected to this signal returns a truthy value, the request is allowed.

    Important: Use **kwargs in your handler signature to ensure compatibility with future updates to the signal arguments.

    To use this, connect a handler to corsheaders.signals.check_request_enabled and ensure the connection is made during the Django app's ready() method.

    # 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)
  8. Configure django-cors-headers settings

    main

    You can configure django-cors-headers by adding the following settings to your Django settings.py file. These settings control which origins, methods, headers, and credentials are allowed during Cross-Origin Resource Sharing (CORS) requests.

    Origin Configuration

    • CORS_ALLOWED_ORIGINS: A list or tuple of allowed origins (e.g., ['https://example.com']). Falls back to CORS_ORIGIN_WHITELIST.
    • CORS_ALLOWED_ORIGIN_REGEXES: A list or tuple of regular expressions for allowed origins. Falls back to CORS_ORIGIN_REGEX_WHITELIST.
    • CORS_ALLOW_ALL_ORIGINS: Boolean. If True, all origins are allowed. Falls back to CORS_ORIGIN_ALLOW_ALL.
    • CORS_ALLOW_PRIVATE_NETWORK: Boolean. If True, allows requests from private networks.

    Request and Response Configuration

    • CORS_ALLOW_METHODS: A sequence of allowed HTTP methods (e.g., ['GET', 'POST', 'OPTIONS']). Defaults to default_methods.
    • CORS_ALLOW_HEADERS: A sequence of allowed HTTP headers. Defaults to default_headers.
    • CORS_ALLOW_CREDENTIALS: Boolean. If True, allows cookies and authentication headers to be included in cross-origin requests. Defaults to False.
    • CORS_EXPOSE_HEADERS: A sequence of headers that the server is allowed to expose to the client.
    • CORS_PREFLIGHT_MAX_AGE: Integer. The maximum age (in seconds) for which the results of a preflight request can be cached. Defaults to 86400.

    URL Filtering

    • CORS_URLS_REGEX: A string or regex pattern that defines which URL paths should be subject to CORS headers. Defaults to r"^.*$" (all paths).
  9. Reference: CORS URL and Method settings

    main

    Optional settings to restrict which URLs and HTTP methods receive CORS headers.

    • CORS_URLS_REGEX: A regex that restricts the URLs for which CORS headers are sent. Defaults to r'^.*$' (all URLs).
    • CORS_ALLOW_METHODS: A list of allowed HTTP verbs. Defaults to DELETE, GET, OPTIONS, PATCH, POST, PUT. You can extend the defaults using corsheaders.defaults.default_methods.
    # Restrict CORS to API paths
    CORS_URLS_REGEX = r"^/api/.*$"
    
    # Extend default allowed methods
    from corsheaders.defaults import default_methods
    CORS_ALLOW_METHODS = (
        *default_methods,
        "POKE",
    )