Docker中的Django:ajax POST失败了csrf

时间:2018-04-12 18:38:32

标签: ajax django docker uwsgi django-csrf

我试图在Docker容器中设置我的Django 1.11应用程序。这是我到目前为止所做的总结:

  • 使用redis,django / uwsgi和jwilder / nginx-proxy:alpine的图像设置docker-compose.yml。 docker-compose build无问题地运行。
  • 设置我的Django代码,以便客户端为每个ajax POST请求发送X-CSRFToken自定义标头。使用runserver运行Django时,此方法正常。
  • 设置我的Django代码以使用redis作为会话缓存。
  • docker-compose.yml中定义的虚拟主机添加到我的/etc/hosts
  • 在Django的dev.mysite.com设置中设置虚拟主机名(ALLOWED_HOSTS)。

此时,我使用docker-compose up运行Docker设置,并使用虚拟主机(dev.mysite.com)在浏览器中访问我的网站。它适用于正常的GET请求,但后续的ajax POST请求在CSRF验证时失败,并出现以下CSRF失败原因:

CSRF token missing or incorrect.

原始响应具有SET-COOKIE标头,其csrf标记与后面的ajax请求包含的X-CSRFToken标头匹配。 ajax POST请求也设置了csrf cookie,该cookie也匹配第一个请求的SET-COOKIE标头。

此时,我不知道为什么CSRF令牌没有在Django的csrf中间件中进行验证,我特别困惑,因为它可以正常使用Django的runserver命令,甚至可以使用提供用于https测试的ssl证书时django-extensions的{​​{1}}命令。

这是我的runserver_plus文件:

docker-compose.yml

Dockerfile:

version: '3'

services:
  django-app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        DJANGO_ENV: ${DJANGO_ENV}
    environment:
      - VIRTUAL_HOST=dev.mysite.com
      - VIRTUAL_PROTO=uwsgi
    restart: always
    ports:
      - "8000:8000"

  redis:
    image: redis:latest
    restart: always
    sysctls:
      - net.core.somaxconn=1024
    volumes:
      - ./data/redis:/data
    command: redis-server --appendonly yes

  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    ports:
      - "80:80"
    environment:
      - ENABLE_IPV6=true
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - ./config/certs:/etc/nginx/certs:ro

devdocker.ini:

FROM python:3.6

RUN apt-get update && \
    apt-get install -y && \
    pip install uwsgi

ARG DJANGO_ENV=devdocker
ENV DJANGO_ENV=$DJANGO_ENV
ENV UWSGI_INI=/opt/mysite/config/uwsgi/${DJANGO_ENV}.ini
ENV DOCKER_CONTAINER=1
ENV UWSGI_ENV=DJANGO_SETTINGS_MODULE=mysite.settings.${DJANGO_ENV}

RUN echo $DJANGO_ENV
COPY . /opt/mysite
WORKDIR /opt/mysite
RUN pip install -r /opt/mysite/requirements/${DJANGO_ENV}.txt
RUN python manage.py collectstatic --no-input --settings=mysite.settings.${DJANGO_ENV}
ENV PYTHONUNBUFFERED=0

EXPOSE 8000

CMD ["sh", "-c", "uwsgi", "--ini", "${UWSGI_INI}"]

设置ajax发布请求(来自Django's docs):

[uwsgi]
socket = 0.0.0.0:8000
chdir = /opt/mysite
module = mysite.wsgi
static-map = /static=/opt/mysite/static
master = 1
processes = 2
threads = 2

请注意,我在devdocker环境的django设置中有function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); ,以及将redis用作会话存储的所有正确设置。另请注意除csrf验证之外的所有内容都有效; GET请求适当返回,静态文件显示正常。

0 个答案:

没有答案