会话 ID 在重定向 django & docker 上发生变化
Session ID getting changed on redirect django & docker
我有一个 Django 和 React 项目。我正在使用 Nginx 和 Gunicorn 运行 应用程序。对于 运行 所有这些,我正在使用 docker。
所以在 Django 视图中,我设置了一个会话变量,然后重定向到另一个视图。所以在那个重定向的视图中,当我试图访问会话变量时,它没有被获取。
我正在使用默认会话将会话存储在 django_session table 中。我也在那里检查过,它正在 django_session table 中获取存储的会话值。但我真的不明白为什么它无法获取会话值。
有线部分在这里,它在 firefox 中可以工作,但在 Chrome 中不能。
通过 运行ning Django 的 运行 服务器命令,同一个项目正在我的本地(没有 docker)工作。
下面是我的 docker-compose.test.yml 文件的样子
version: "3.8"
services:
db:
image: postgres:12.3
ports:
- "5432:5432"
env_file:
- ./env/.env.dev.db
volumes:
- postgres_data:/var/lib/postgresql/data/
networks:
- backend
app:
build:
context: .
dockerfile: ./docker/test-env/app-docker/Dockerfile
args:
- REACT_APP_API_URL=http://127.0.0.1
volumes:
- app_static_files:/app/static
command: >
/bin/sh -c
"python manage.py migrate
&& python manage.py collectstatic --no-input
&& gunicorn -w 4 --bind 0.0.0.0:8000 app.wsgi
"
env_file:
- ./env/.env.dev.db
- ./env/.env.dev
ports:
- "8000:8000"
depends_on:
- db
networks:
- backend
nginx:
build:
context: .
dockerfile: ./docker/test-env/nginx/Dockerfile
ports:
- "80:80"
- "443:443"
volumes:
- app_static_files:/project_static_files
depends_on:
- app
networks:
- backend
volumes:
postgres_data:
app_static_files:
networks:
backend:
这就是我的应用 docker 文件的样子。
# BUILD FRONT END
FROM node:12.17.0-alpine3.11 as frontend
ARG REACT_APP_API_URL
ENV REACT_APP_API_URL $REACT_APP_API_URL
WORKDIR /app
COPY ./app/front_end/app-frontend/ /app
RUN npm install
RUN npm run build
# APPLICATION
FROM python:3.8.3-slim
ENV PATH="/app:${PATH}"
WORKDIR /app
RUN apt-get update && apt-get install -y gcc libxml2-dev libxmlsec1-dev pkg-config \
&& apt-get -y install libsasl2-dev libldap2-dev libssl-dev libxmlsec1-openssl python3-dev
COPY ./app/ /app
COPY --from=frontend /app/build /app/front_end/noa-frontend/
RUN pip install -r production_requirements.txt --no-cache-dir
下面是Nginx配置
server {
listen 80;
server_name $server_addr;
access_log /var/log/nginx/example.log;
location /static/ {
autoindex off;
alias /project_static_files/;
}
location / {
proxy_pass http://app:8000;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
请有人帮助我,我在互联网上找不到任何关于此的信息。
我运行正在进行的这个项目
- Windows 10 亲
- Docker 版本 19.03.8,构建 afacb8b
- docker-compose version 1.25.5, build 8a1c60f6
更新:
我也尝试了 Django 的 运行 服务器来测试它是否至少可以在 docker 容器中与 Django 的 运行 服务器一起工作。但是没有,我在 Chrome 中遇到了同样的问题,但在 Firefox 中它工作正常:(
在我看到的错误中,只有 csrftoken 被传递到 Chrome。而对于 Firefox,csrftoken 和 sessionid 都被传递。
Cookie 传递给 Chrome
传递给 Firefox 的 Cookie
我明白是怎么回事了。
我有一个环境变量文件。在那,我设置了下面的行
SESSION_COOKIE_SECURE_VAL=0
CSRF_COOKIE_SECURE_VAL=0
DEV_ENV=1
在 settings.py 我有
SESSION_COOKIE_SECURE = bool(int(os.environ.get("SESSION_COOKIE_SECURE_VAL")))
CSRF_COOKIE_SECURE = bool(int(os.environ.get("CSRF_COOKIE_SECURE_VAL")))
所以 0 代表 False,1 代表 True。尽管我已经为 SESSION_COOKIE_SECURE 和 CSRF_COOKIE_SECURE 设置了 0 (False),但它使用的是 1,即 True(我真的不知道为什么默认使用 1,即使我正在设置环境这些值)
在Django文档中,是这样提到的
所以我所做的就是更改 settings.py 文件中的逻辑,如下所示
if not bool(int(os.environ.get("DEV_ENV", default=1))):
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
所以我的开发环境不是HTTPS,所以检查它是否不是开发环境然后不要设置SESSION_COOKIE_SECURE和CSRF_COOKIE_SECURE(在这种情况下两者都默认为False)
我不确定为什么 Firefox 能够在此设置下设置 cookie。
如果有更好的回答请回答。
如果有人遇到同样的问题,我希望这会有所帮助。
我有一个 Django 和 React 项目。我正在使用 Nginx 和 Gunicorn 运行 应用程序。对于 运行 所有这些,我正在使用 docker。
所以在 Django 视图中,我设置了一个会话变量,然后重定向到另一个视图。所以在那个重定向的视图中,当我试图访问会话变量时,它没有被获取。
我正在使用默认会话将会话存储在 django_session table 中。我也在那里检查过,它正在 django_session table 中获取存储的会话值。但我真的不明白为什么它无法获取会话值。
有线部分在这里,它在 firefox 中可以工作,但在 Chrome 中不能。
通过 运行ning Django 的 运行 服务器命令,同一个项目正在我的本地(没有 docker)工作。
下面是我的 docker-compose.test.yml 文件的样子
version: "3.8"
services:
db:
image: postgres:12.3
ports:
- "5432:5432"
env_file:
- ./env/.env.dev.db
volumes:
- postgres_data:/var/lib/postgresql/data/
networks:
- backend
app:
build:
context: .
dockerfile: ./docker/test-env/app-docker/Dockerfile
args:
- REACT_APP_API_URL=http://127.0.0.1
volumes:
- app_static_files:/app/static
command: >
/bin/sh -c
"python manage.py migrate
&& python manage.py collectstatic --no-input
&& gunicorn -w 4 --bind 0.0.0.0:8000 app.wsgi
"
env_file:
- ./env/.env.dev.db
- ./env/.env.dev
ports:
- "8000:8000"
depends_on:
- db
networks:
- backend
nginx:
build:
context: .
dockerfile: ./docker/test-env/nginx/Dockerfile
ports:
- "80:80"
- "443:443"
volumes:
- app_static_files:/project_static_files
depends_on:
- app
networks:
- backend
volumes:
postgres_data:
app_static_files:
networks:
backend:
这就是我的应用 docker 文件的样子。
# BUILD FRONT END
FROM node:12.17.0-alpine3.11 as frontend
ARG REACT_APP_API_URL
ENV REACT_APP_API_URL $REACT_APP_API_URL
WORKDIR /app
COPY ./app/front_end/app-frontend/ /app
RUN npm install
RUN npm run build
# APPLICATION
FROM python:3.8.3-slim
ENV PATH="/app:${PATH}"
WORKDIR /app
RUN apt-get update && apt-get install -y gcc libxml2-dev libxmlsec1-dev pkg-config \
&& apt-get -y install libsasl2-dev libldap2-dev libssl-dev libxmlsec1-openssl python3-dev
COPY ./app/ /app
COPY --from=frontend /app/build /app/front_end/noa-frontend/
RUN pip install -r production_requirements.txt --no-cache-dir
下面是Nginx配置
server {
listen 80;
server_name $server_addr;
access_log /var/log/nginx/example.log;
location /static/ {
autoindex off;
alias /project_static_files/;
}
location / {
proxy_pass http://app:8000;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
请有人帮助我,我在互联网上找不到任何关于此的信息。
我运行正在进行的这个项目
- Windows 10 亲
- Docker 版本 19.03.8,构建 afacb8b
- docker-compose version 1.25.5, build 8a1c60f6
更新:
我也尝试了 Django 的 运行 服务器来测试它是否至少可以在 docker 容器中与 Django 的 运行 服务器一起工作。但是没有,我在 Chrome 中遇到了同样的问题,但在 Firefox 中它工作正常:(
在我看到的错误中,只有 csrftoken 被传递到 Chrome。而对于 Firefox,csrftoken 和 sessionid 都被传递。
Cookie 传递给 Chrome
传递给 Firefox 的 Cookie
我明白是怎么回事了。
我有一个环境变量文件。在那,我设置了下面的行
SESSION_COOKIE_SECURE_VAL=0
CSRF_COOKIE_SECURE_VAL=0
DEV_ENV=1
在 settings.py 我有
SESSION_COOKIE_SECURE = bool(int(os.environ.get("SESSION_COOKIE_SECURE_VAL")))
CSRF_COOKIE_SECURE = bool(int(os.environ.get("CSRF_COOKIE_SECURE_VAL")))
所以 0 代表 False,1 代表 True。尽管我已经为 SESSION_COOKIE_SECURE 和 CSRF_COOKIE_SECURE 设置了 0 (False),但它使用的是 1,即 True(我真的不知道为什么默认使用 1,即使我正在设置环境这些值)
在Django文档中,是这样提到的
所以我所做的就是更改 settings.py 文件中的逻辑,如下所示
if not bool(int(os.environ.get("DEV_ENV", default=1))):
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
所以我的开发环境不是HTTPS,所以检查它是否不是开发环境然后不要设置SESSION_COOKIE_SECURE和CSRF_COOKIE_SECURE(在这种情况下两者都默认为False)
我不确定为什么 Firefox 能够在此设置下设置 cookie。
如果有更好的回答请回答。
如果有人遇到同样的问题,我希望这会有所帮助。