强制 HTTPS、代理和邀请相关的问题

我的 Discourse 实例位于代理之后:

server {
    server_name forum.[...];

    location / {
        proxy_pass http://IP_ADDRESS;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;

    }

    client_max_body_size 10m;

    listen 443 ssl; # 由 Certbot 管理
    ssl_certificate /etc/letsencrypt/live/forum.[...]/fullchain.pem; # 由 Certbot 管理
    ssl_certificate_key /etc/letsencrypt/live/forum.[...]/privkey.pem; # 由 Certbot 管理
    include /etc/letsencrypt/options-ssl-nginx.conf; # 由 Certbot 管理
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # 由 Certbot 管理

}
server {
    if ($host = forum.[...]) {
        return 301 https://$host$request_uri;
    } # 由 Certbot 管理

    server_name forum.smbcn.org;

    listen 80;
    return 404; # 由 Certbot 管理

}

这会导致 Discourse 安装所在的服务器(标准 Docker 安装)出现以下配置:

server {
        listen 80; listen [::]:80;
        server_name forum.[...];

        client_max_body_size 10m;

        location / {
                proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
                proxy_set_header Host $http_host;
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
        }
}

当我强制启用 HTTPS 时,被邀请的用户无法继续注册。浏览器日志显示 403 错误(CSRF 无效),尽管 CSRF 令牌已成功生成。如果不强制 HTTPS,邀请功能则正常工作。

我猜测问题可能出在我将 HTTPS 请求代理到 HTTP 的方式上,也许是缺少某些请求头?

1 个赞

看起来我确实漏掉了什么。无法强制使用 HTTPS 意味着 Logo 无法显示(目前还不算太严重)。我今天刚发现,当我尝试在 Sidekiq 中删除任务时,还会遇到一个与 CSRF 相关的错误(“禁止访问”)。我在 /var/discourse/shared/standalone/log/rails/unicorn.stderr.log 中发现了以下内容:

WARN – : 攻击已被 Rack::Protection::HttpOrigin 阻止

我感到相当无助,任何帮助都将不胜感激。

1 个赞

也许你只需要在前置代理上强制启用 HTTPS,并在 Discourse 上禁用它。

@hawm 我想这是我当前的配置。

你是如何设置 $scheme 变量的?

3 个赞

我没有设置,我想我是依赖默认值的,这样对吗?

如果您正在使用代理,这可能会出问题。根据我的经验,这是导致您所描述问题的首要原因。尝试将其设置为“https”(或者干脆跳过该变量,直接在那里填入“https”)。

2 个赞

@michaeld 是的!你完全说对了!非常感谢!

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.