Django-приложение испытывает ошибку "CSRF token missing" специально для POST-запросов при развертывании с Nginx и Gunicorn
Я развернул приложение Django, используя Nginx и Gunicorn, и столкнулся с ошибкой "CSRF token missing" специально для POST-запросов. Вот краткий обзор моих настроек:
Я развернул свое приложение Django на сервере Ubuntu, используя nginx и gunicorn. Мое приложение Django отлично работало при локальном использовании, но теперь на сервере я получаю эту ошибку только при выполнении POST-запросов:
{
"detail": "CSRF Failed: CSRF token missing."
}
[Это руководство, которому мы следовали, чтобы настроить все на нашем сервере] (https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu)
Для аутентификации мы используем django_auth_adfs (microsoft).
Вот мои установочные файлы:
- nginx/sites-available/<our_project>:
server {
server_name <our_domain.com>;
ignore_invalid_headers off;
underscores_in_headers on;
location / {
root <location/to/frontend>;
}
location /oauth2/ {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /login_redirect {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ~ \.well-known {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /api/ {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /admin/ {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/sel2-4.ugent.be/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/sel2-4.ugent.be/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = <our_domain.com>) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name <our_domain.com>;
return 404; # managed by Certbot
}
- Файл Setings.py для django:
- Вот одно из представлений Django, которое выдает ошибку (при отправке POST-запроса мы даже не вводим этот блок кода, поэтому ошибка возникает перед представлением):
@api_view(['GET', 'POST'])
def vak_list(request, format=None):
if request.method == 'GET':
if is_lesgever(request.user):
vakken = Vak.objects.all()
else:
vakken = Vak.objects.filter(studenten=request.user.id)
serializer = VakSerializer(vakken, many=True)
return Response(serializer.data)
elif request.method == 'POST':
if is_lesgever(request.user):
serializer = VakSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response(status=status.HTTP_403_FORBIDDEN)
- Все остальные файлы конфигурации являются файлами по умолчанию. Запросите любой другой файл, если он нужен для уточнения.
Любая помощь будет очень признательна, потому что я ищу решение уже несколько часов.
После тестирования без использования Gunicorn стало ясно, что Gunicorn не является причиной проблемы. Кроме того, при отправке GET-запросов токен CSRF правильно включается в заголовки Cookie, что указывает на то, что Nginx не удаляет никаких важных заголовков. Однако ошибка сохраняется только при входе пользователей в систему. Хотя временным решением проблемы является выход пользователей из системы, это не является жизнеспособным решением, так как для корректной работы системы пользователи должны быть зарегистрированы. Cookie отправляется из браузера в заголовках.