Skip to content

Cross-Origin Resource Sharing

In a decoupled setup, JavaScript is the main consumer for REST and GraphQL APIs.

By default, JavaScript can request resources with XMLHttpRequest or fetch, as long as the server and the frontend live in the same origin.

An origin in HTTP is the combination of the scheme or protocol, the domain, and the port. This means that the origin http://localhost:8000 is not equal to http://localhost:3000.

When JavaScript attempts to fetch a resource from a different origin than its own, a mechanism known as Cross-Origin Resource Sharing (CORS) kicks in the browser. In any REST or GraphQL project, CORS is necessary to control what origins can connect to the API. To enable CORS in Django, we can install django-cors-headers in our project with the following command:

Python
pip install django-cors-headers

Enabling django-cors-headers in Django

To enable the package, include corsheaders in decoupled_dj/settings/base.py, as shown in Listing 7-10.

INSTALLED_APPS = [
...
'corsheaders',
...
]

Enabling CORS Middleware

MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]

With this change in place, we can configure django-cors-headers. In development, we may want to allow all origins to bypass CORS altogether. To decoupled_dj/settings/development.py, add the configuration shown in Listing 7-12.

Relaxing CORS in Development

CORS_ALLOW_ALL_ORIGINS = True

In production, we have to be more restrictive. django-cors-headers allows us to define a list of allowed origins, which can be configured in decoupled_dj/settings/production.py

Hardening CORS in Production

CORS_ALLOWED_ORIGINS = [
    "https://example.com",
    "http://another1.io",
    "http://another2.io",
]

Since we are using variables per environment, we can make this configuration directive a list

CORS_ALLOWED_ORIGINS = env.list(
    "CORS_ALLOWED_ORIGINS",
    default=[]
)

This way we can define allowed origins as a comma-separated list in .env for production. CORS is a basic form of protection for users, since without this mechanism in place, any website would be able to fetch and inject malicious code in the page, and a protection for REST APIs, which can explicitly allow a list of predefined origins instead of being open to the world. Of course, CORS does not absolutely replace authentication, which is covered briefly in the next section.


Reference

Book