【问题标题】:Django authentication fails with nginx and gunicorn but works with run_serverDjango 身份验证使用 nginx 和 gunicorn 失败,但适用于 run_server
【发布时间】:2021-09-28 04:06:13
【问题描述】:

我已经阅读了无数文章并倾注了这个问题,但我还没有答案。我有一个标准系统在 docker 中运行,带有 docker-compose,它有 nginx 作为 gunicorn 的反向代理和默认的 django 身份验证系统。我通过设置表单类重新设计了登录页面,但这就是我所拥有的所有自定义项。

当我在 run_server 中运行我的网站进行调试时,一切正常。我进入登录页面,成功登录,然后被重定向。 is_authenticated 产生例外结果。我在 nginx 和 gunicorn 后面运行完全相同的页面,我得到了非常奇怪的行为。通常我会成功登录,我的 sessionid 与数据库中的会话匹配,csrf 令牌与数据库中的内容匹配,但 is_authenticated 为 false。但只有大约 90% 的时间。通常,我会使用 url 上的 login_required 装饰器 (login_required(view.as_view()) 访问一个需要登录的页面,它会让我多次登录,is_authenticated 每次都是假的,直到它工作并且什么时候工作, is_authenticated 在登录页面后设置为 false。

这是我的 nginx 配置。请注意,django 是 docker-compose 分配的 IP 地址,而 gunicorn 运行在 8050 端口上。这真的很标准:

server {
    listen       80;
    server_name  _;

    #charset koi8-r;
    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    #location / {
    #    root   /usr/share/nginx/html;
    #    index  index.html index.htm;
    #}

    location /static/ {
        autoindex on;
        alias /static/;
    }

    location /pgadmin4/ {
        # forward application requests to the gunicorn server

        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Script-Name /pgadmin4;

        # Changing timeout behavior
        proxy_read_timeout 300;
        proxy_pass http://pgadmin;
    }

    location / {
        # forward application requests to the gunicorn server
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Changing timeout behavior
        proxy_read_timeout 300;
        proxy_pass http://django:8050;
    }
}

这里是 settings.py 的相关部分

INSTALLED_APPS = [
    'cvi.apps.CviConfig',
    'crispy_forms',
    'notes.apps.NotesConfig',
    'scenarios.apps.ScenariosConfig',
    'tsmodels.apps.TsmodelsConfig',
    'services.apps.ServicesConfig',
    'model_info.apps.ModelInfoConfig',
    'data_tools.apps.DataToolsConfig',
    'demos.apps.DemosConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'bootstrap_datepicker_plus',
    'wkhtmltopdf'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

WSGI_APPLICATION = 'DataManagement.wsgi.application'

这里是 gunicorn 运行脚本:

exec gunicorn DataManagement.wsgi:application \
    --name=DataManagement \
    --workers=4 \
    --log-level=debug \
    --bind=0.0.0.0:8050 \
    --timeout=600 \
    --log-file=./gunicorn.log \
    --log-level=debug

此配置无需身份验证即可工作。我将 login_required 添加到我的 url 的第二个是当出现身份验证问题时。我真的很感激你能提供的任何帮助。我之前在其他 django 网站上设置用户身份验证时从未遇到过这个问题。

【问题讨论】:

  • 我看到您在安装的应用程序中有 DRF。 Django auth 和 DRF auth 的工作方式不同。如果有问题的视图是 DRF 视图,请尝试使用 DRF 方法。 DRF auth docs
  • 我应该提到该视图不是 REST API,我正在通过 chrome 使用 http 请求。另外,我注释掉了“rest_framework”安装的应用程序,问题仍然存在。

标签: django authentication nginx reverse-proxy gunicorn


【解决方案1】:

问题是缺少文档和配置选项。我们在 Django 中使用了SECRET_KEY,显然这里没有复制。根据文档,我们有一个用于开发环境的get_random_secret_key()。这不适用于多个 gunicorn 工人。每个工人将启动一个新终端,从而为每个工人获得一个新的 SECRET_KEY。密钥显然在 Django 身份验证系统中的某个地方使用。您无法控制哪个工作人员从 nginx 接收您的请求,因此您可能有一个工作人员处理 3 或 4 个请求,或者有 4 个工作人员处理 4 个请求。

线程显然也不继承密钥,因此实际上只有一种解决方案可以使用固定密钥。工人从相同的密钥开始,它似乎工作。

这在 Django 或 gunicorn 中没有记录,默认的工作示例将无法通过身份验证。

【讨论】:

  • Niiii​​ice,这才是真正的问题所在。谢谢
猜你喜欢
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 2022-01-11
  • 2012-10-21
  • 2018-11-02
  • 2016-05-09
相关资源
最近更新 更多