13

我对 python 比较陌生,我使用flask-resplus创建了一个微服务。在我的计算机和使用 http 服务的开发服务器上工作正常。我无法控制微服务的部署位置。在这种情况下,它似乎位于负载均衡器后面(不确定细节),使用 https 提供服务。

浏览器给出的实际错误:无法从服务器读取。它可能没有适当的访问控制来源设置。

当我检查网络开发人员工具时,我发现它无法加载 swagger.json。但是正在使用: http://hostname/api/swagger.json而不是 https 来检查它。

我一直在谷歌搜索,我遇到了这个问题的讨论。这似乎是无需更改服务器上的库或配置即可工作的修复程序

但是我仍然无法让它工作。

这就是我所拥有的:

在 api 文件上:

api_blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(api_blueprint, doc='/doc/', version='1.0', title='My api',
          description="My api")

在主应用程序文件上:

from flask import Flask
from werkzeug.contrib.fixers import ProxyFix

from lib.api import api_blueprint

app = Flask(__name__)

app.wsgi_app = ProxyFix(app.wsgi_app)
app.register_blueprint(api_blueprint)

还尝试添加:

app.config['SERVER_URL'] = 'http://testfsdf.co.za' # but it dont look like is being considered

使用烧瓶-restplus==0.9.2,

任何解决方案都会受到赞赏,只要我不需要在将部署服务的容器上进行配置(可以设置环境变量),即服务需要是自包含的。如果有一个我可以用 pip 安装的 flask-resplus 版本,那已经有一个我可以欣赏的修复程序。

非常感谢各位,

4

2 回答 2

10

_scheme='https'使用属性中的选项覆盖 API 类spec

class MyApi(Api):
    @property
    def specs_url(self):
        """Monkey patch for HTTPS"""
        scheme = 'http' if '5000' in self.base_url else 'https'
        return url_for(self.endpoint('specs'), _external=True, _scheme=scheme)

api = MyApi(api_blueprint, doc='/doc/', version='1.0', title='My api',
        description="My api")
于 2018-08-02T04:33:40.827 回答
2

上面的解决方案就像一个魅力。您应该检查几件事。

  1. 在应用修复之前,请确保在您的chrome developertools -> Network选项卡中,每当您重新加载显示 swagger UI 的页面(在 https 服务器中)时,您都会收到 swagger.json 请求的混合内容错误。

  2. 上述帖子中的解决方案在部署在 https 服务器上时解决了该问题,但在本地可能会出现问题。为此,您可以使用环境变量技巧。

  3. 在部署应用程序时设置自定义环境变量或 https 服务器上已有的任何变量。在应用解决方案之前检查该环境变量是否存在,以确保您的应用程序在 https 服务器中运行。

现在,当您在本地运行应用程序时,将不会应用此 hack,并且 swagger.json 将通过http提供服务,而在您的服务器中,它将通过https提供服务。实现可能与此类似。

import os
from flask import url_for
from flask_restplus import Api

app = Flask( __name__)
if os.environ.get('CUSTOM_ENV_VAR'):
    @property
    def specs_url(self):
        return url_for(self.endpoint('specs'), _external=True, _scheme='https')
    Api.specs_url = specs_url
api = Api(app)
于 2020-06-17T18:35:45.863 回答