Background Light
How to protect access from other site of your json data

How to protect access from other site of your json data

To protect your JSON data from being accessed by "other sites" (meaning different domains/origins) when a browser is making a request, you need to implement Cross-Origin Resource Sharing (CORS).

Browsers enforce a security feature called the Same-Origin Policy. This policy prevents a web page from making requests to a different domain than the one that served the page. This is a fundamental security measure to prevent malicious websites from reading sensitive data from other sites (e.g., your bank's website) that a user might be logged into.

However, in modern web development, it's very common to have your frontend (e.g., a React app on myapp.com) on a different domain or subdomain than your backend API (e.g., api.myapp.com). CORS is the mechanism that allows the server to explicitly tell the browser: "Yes, it's okay for scripts from this specific origin to access my resources."

For Django, the standard way to handle CORS is by using the django-cors-headers package.


Steps to Implement CORS in Django using django-cors-headers

Goal: Allow only your trusted frontend origins to access your API data, while blocking others.

1. Install django-cors-headers

In your virtual environment (on your server and/or local development machine):

Bash

pip install django-cors-headers
 

2. Configure eyewebmaster/settings.py

You need to add corsheaders to INSTALLED_APPS and include its middleware.

project/settings.py (CORS Configuration)

Key Points in settings.py for CORS:

  • Placement in INSTALLED_APPS and MIDDLEWARE: Correct order is vital. corsheaders.middleware.CorsMiddleware must come before django.middleware.common.CommonMiddleware.
  • CORS_ALLOWED_ORIGINS (Production Best Practice): This is the most important setting. List only the specific domains from which your API should accept cross-origin requests. Any request coming from an origin not in this list will be blocked by the browser.
  • CORS_ALLOW_ALL_ORIGINS = True (Development Only): Never use this in production. It effectively disables CORS security, allowing any website to make requests to your API.
  • CORS_ALLOWED_ORIGIN_REGEXES: Use this if you have multiple subdomains or dynamic origins that you need to allow.
  • CORS_ALLOWED_METHODS & CORS_ALLOWED_HEADERS: You usually don't need to specify these unless you are restricting them. However, if your frontend sends custom headers (like X-Custom-Header) or uses specific methods (like PUT, DELETE), you might need to explicitly list them. authorization is critical for JWT.
  • CORS_URLS_REGEX: If only your /api/ endpoints need CORS, this is an excellent way to restrict the application of CORS headers to only those paths, preventing unnecessary headers on your regular Django views.

3. Restart Your Django Server

After making changes to settings.py, save the file and restart your Django development server or your production Gunicorn service.

Bash

python manage.py runserver # For development
# For production (after updating gunicorn.service if needed):
# sudo systemctl daemon-reload
# sudo systemctl restart gunicorn
 

How it Protects Your Data:

Once correctly configured, when a browser on evil-site.com tries to make a JavaScript fetch or XMLHttpRequest to your-api.com/api/posts/, the browser will first send an "OPTIONS" preflight request. Your Nginx/Gunicorn will pass this to Django, django-cors-headers will inspect the Origin header, and if evil-site.com is not in your CORS_ALLOWED_ORIGINS list, it will respond with headers that tell the browser, "No, access is denied." The browser will then block the actual request, and the JavaScript on evil-site.com will not receive your JSON data.

Important Caveat: CORS is a browser-enforced security mechanism. It does not prevent non-browser clients (like curl, Postman, mobile apps, or other backend servers) from making requests to your API, as they don't respect the Same-Origin Policy. To protect against such clients, you must rely on:

  • Authentication (JWT, API Keys, OAuth2): To verify who is making the request.
  • Authorization (DRF Permissions): To verify what they are allowed to do.
  • HTTPS: To protect data in transit from any client.