skip to Main Content

I am running a Django app behind Nginx in a Docker environment. My problem is sort of the same from this thread: Django returning "CSRF verification failed. Request aborted. " behind Nginx proxy locally.

Upon learning that I have to add CSRF_TRUSTED_ORIGINS in settings, since I am using Django version 4.X, I added my localhost

CSRF_TRUSTED_ORIGINS = [
    'http://localhost',
    'http://localhost:3000',
    'https://example.com',
]

I can login to my admin when the container is deployed locally. However, when I deployed it to production, I still get the error:

CSRF verification failed. Request aborted.

I deployed it in a Google compute engine. The app does not have a domain name yet. Thus, I visit the app using its external address of the machine: http://XX.XX.XX.XX/admin. Should I add this address to my CSRF_TRUSTED_ORIGINS? My understanding is that this is the same as adding the localhost http://localhost since I am visiting the host machine’s address.

CSRF_TRUSTED_ORIGINS = [
    'http://localhost',
    'http://localhost:3000',
    'https://example.com',
    'http://XX.XX.XX.XX'
]

What if I deployed it to another machine with a different address? Should I again add it? Is there any other way to allow the CSRF without specifically adding the address since it would be tedious if I would be changing/migrating in host machines?

This is my nginx config, if it is of any help.

upstream api {
    server container_name:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://api;
    }

    location /static/ {
        alias /static/;
    }
}

3

Answers


  1. Your question about adding the IP address of another machine, you would need to add it to your CSRF_TRUSTED_ORIGINS settings as well. There’s no other way to allow CSRF without explicitly adding the origin to the trusted list.

    If you don’t want to add specific IP addresses or domain names to the trusted list, you can disable CSRF protection altogether by removing the CsrfViewMiddleware middleware from your MIDDLEWARE settings. However, this is not recommended since it could leave your app vulnerable to CSRF attacks.

    Login or Signup to reply.
  2. On production, the settings of Django works a bit different. You can try these 2 things:

    1. In setting.py add CSRF_TRUSTED_ORIGINS = ['https://your-domain.com']
    2. In setting.py add STATIC_URL = 'static/' or whatever path you change in your nginx config.

    Since you’re using it behind proxy there are chances that the js and CSS might not be served properly. In that case #2 is useful.

    Login or Signup to reply.
  3. In CSRF Trusted origins list add the container name, that should resolve the issue.

    CSRF_TRUSTED_ORIGINS = [
        'http://localhost',
        'http://localhost:3000',
        'https://example.com',
        'http://XX.XX.XX.XX',
        'container_name'
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search