登录失败,显示“未知错误”

你好,

我正在运行自己的 Discourse 实例,我是按照基础的 Docker 安装指南 安装的。我遇到的问题是在论坛使用几天后,登录功能完全失效。请注意,我是该论坛的唯一用户。但遗憾的是,我不知道是什么导致了这个错误。

复现步骤 #1

  1. 按照 Docker 安装指南的说明安装新的 Discourse 服务器。
  2. 设置向导完成后,验证是否可以成功注销并重新登录。
  3. 像往常一样继续使用论坛。只需创建一些分类和帖子,或者更改默认主题。
  4. 在正常使用几天或几周后,注销后将无法再次登录。登录失败并显示“未知错误”(显示在登录表单上)。

复现步骤 #2

  1. 按照 Docker 安装指南的说明安装新的 Discourse 服务器。
  2. 设置向导完成后,验证是否可以成功注销并重新登录。
  3. 从另一个登录功能失效的 Discourse 实例恢复备份。
  4. 在恢复过程中,会弹出一条消息提示您已被注销。恢复成功,但登录失败并显示“未知错误”(显示在登录表单上)。

我曾尝试自行调试该问题,但未能找到任何相关的错误信息。以下是我到目前为止所做的尝试:

cd /var/discourse
./launcher enter app
tail -F log/production_errors.log
tail -F log/production.log
tail -F log/unicorn.stderr.log
tail -F log/unicorn.stdout.log

在登录失败期间,这些日志中并未出现任何错误信息。我还能做些什么来帮助调试这个问题?提前感谢。

作为管理员登录时,你在网页浏览器中查看过 /logs 吗?

好的,我找到问题了。一旦启用“强制 HTTPS

终于找到了解决方案。必须设置 X-Forwarded-Proto 头部,该头部用于识别客户端连接到您的代理或负载均衡器时使用的协议(HTTP 或 HTTPS)。

由于我使用 HAProxy 作为代理服务器,因此必须在 HAProxy 配置中添加以下行:

http-request set-header X-Forwarded-Proto https if { ssl_fc }

现在,即使启用了“强制 HTTPS

我也希望在连接到我的 Discourse 服务器的任何连接上使用 PROXY 协议。PROXY 协议会告知另一端(即 Discourse 服务器)传入连接的地址,使其能够获知客户端地址或其访问的公共地址。若不进行此更改,Nginx 将无法识别客户端地址,所有日志将仅记录反向代理服务器的地址。以下更改即可实现该功能:

root@talk3:/var/discourse# git diff
diff --git a/templates/web.template.yml b/templates/web.template.yml
index a60e6ef..55cb5f2 100644
--- a/templates/web.template.yml
+++ b/templates/web.template.yml
@@ -116,6 +116,19 @@ run:
       to: daemon off;

   - replace:
+      filename: /etc/nginx/nginx.conf
+      from: /# server_tokens off;/
+      to: |
+        server_tokens off;
+        real_ip_header proxy_protocol;
+        set_real_ip_from 192.168.1.19;  # 代理服务器地址
+
+  - replace:
+      filename: "/etc/nginx/conf.d/discourse.conf"
+      from: /listen 80;$/
+      to: "listen 80 proxy_protocol;"
+
+  - replace:
       filename: "/etc/nginx/conf.d/discourse.conf"
       from: /upstream[^\}]+\}/m
       to: "upstream discourse {

并指示 HAProxy 对该服务器强制启用 PROXY 协议:

-    server server-1 192.168.1.27:80 check
+    server server-1 192.168.1.27:80 check send-proxy

最后执行 ./launcher rebuild app,并验证日志是否现在记录了客户端地址:

tail -F /var/discourse/shared/standalone/log/var-log/nginx/access.log