8

如果我尝试通过 HTTPS 使用 Flask RestPlus 交付 Swagger UI,我只会在根 URL 处看到“未提供规范”错误消息,并且永远不会加载完整的 Swagger UI。但是,如果我访问 API 端点,它们会按预期返回响应。

查看错误页面的源 HTML,我注意到它swagger.json是从而http://myhost/不是从https://myhost/

我在 restplus Github 问题上发现了完全相同的问题

我已经使用该页面上提到的猴子补丁暂时解决了我的问题。Swagger UI 加载,查看我看到的 HTML 源代码swagger.json确实是从https://myhost.

为什么会发生这种情况,如果没有猴子补丁,我该如何解决?

HTTPS 由 Cloudflare 的“灵活”HTTPS 服务提供。

我的应用程序在 Nginx 后面,它是这样配置的,据我所知,并没有引起任何问题:

...
http {
  ...
  server {
    location / {
      charset UTF-8;
      try_files $uri @proxy_to_app;
    }
    location @proxy_to_app {
      charset UTF-8;
      proxy_intercept_errors on;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://127.0.0.1:5000;
    }
  }
}
4

3 回答 3

4

我在下面使用它来让它工作。您可以在下面的链接中查看稳定的示例。

http://flask-restplus.readthedocs.io/en/stable/example.html

from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
于 2018-07-19T04:13:32.963 回答
0

我有这个问题。

当我查看“未提供规范”错误页面的来源时,我可以在底部看到:

 window.onload = function() {
            const ui = window.ui = new SwaggerUIBundle({
                url: "http://127.0.0.1:5000/api/v1/swagger.json",
                validatorUrl: "" || null,
                dom_id: "#swagger-ui",
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset.slice(1) // No Topbar
                ],
                plugins: [
                    SwaggerUIBundle.plugins.DownloadUrl
                ],
                displayOperationId: false,
                displayRequestDuration: false,
                docExpansion: "none"
            })

请注意,uri 是http://127.0.0.1:5000。这表明主机名和协议没有被传递给服务器(在我的例子中是 Gnuicorn)。

为了解决这个问题,我在我的 ngnix 配置中添加了以下内容:

        location / {
                # new lines
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Host $host;

                # this already existed
                proxy_pass http://127.0.0.1:5000;
        }

请注意,我必须在ssl服务器块中添加它。当我第一次尝试它时,我把它放在非 SSL 部分,它没有任何区别。

于 2020-05-18T05:44:02.100 回答
0

我不确定这是否完全安全,但这是我在 Nginx 中修复它的方法:

sub_filter "http://$host/" "https://$host/";
sub_filter_once off;
proxy_redirect    off;

我正在 Nginx 上卸载 SSL,这对我来说没有任何问题。它还消除了猴子补丁应用程序代码的需要。

您从 flask-restplus 问题中列出的方法绝对被认为是不安全的:

Please keep in mind that it is a security issue to use such a
middleware in a non-proxy setup because it will blindly trust
the incoming headers which might be forged by malicious clients.
于 2018-07-13T06:19:34.407 回答