我知道在传统的 swagger YAML 文件中,我们可以使用以下方式定义方案:
schemes:
- http
- https
//OR
schemes: [http, https]
但是,如何使用
drf-yasg
库自动生成的 swagger 页面做同样的事情?
现在,生成的swagger页面仅包含
HTTP
方案,但缺少HTTPS
。我尝试将 DEFAULT_API_URL
中的 setting.py
设置为 https://mybaseurl.com
,但似乎不起作用。
要在 swagger 中同时使用 http 和 https 方案,您可以从
OpenAPISchemaGenerator
扩展 drf_yasg.generators
。
class BothHttpAndHttpsSchemaGenerator(OpenAPISchemaGenerator):
def get_schema(self, request=None, public=False):
schema = super().get_schema(request, public)
schema.schemes = ["http", "https"]
return schema
所以现在您可以将其用作
generator_class
的 get_schema_view()
schema_view = get_schema_view(
openapi.Info( ... ),
public=True,
generator_class=BothHttpAndHttpsSchemaGenerator, # Here
permission_classes=(AllowAny,)
)
有一个解决方案。
在
urls.py
中定义get_schema_view()时,使用以下代码:
schema_view = get_schema_view(
openapi.Info( ... ),
url='https://example.net/api/v1/', # Important bit
public=True,
permission_classes=(permissions.AllowAny,)
)
注意:您可以使用 https 或 http,因为更好地将此解决方案与环境变量一起用于不同的设置。
在 swagger 页面中使用
https
方案的另一种方法是使用 SECURE_PROXY_SSL_HEADER
配置。
假设您的 Django REST API 位于正在执行 SSL 终止的 Nginx 后面,您可以让 Nginx 将
X-Forwarded-Proto: https
转发到您的 Django 应用程序(Nginx 可能已经默认转发此标头,具体取决于您的设置方式) 。通过下面的配置,您的 Django 应用程序将意识到它位于 SSL 终止 Nginx 后面,并且当标头存在时,Django 的内部函数 is_secure()
将返回 True
。 请参阅 Django SSL 设置。
一旦
is_secure()
返回True
,swagger页面方案将自动变成https
。
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
我喜欢这种方法,因为它不需要任何硬编码 url,甚至不需要从环境变量配置 url。此外,
is_secure()
函数也在其他地方内部使用,因此希望该函数能够按理想情况工作。
放置
url='https://your_server_address/'
在带有 URL 的 get_schema_view() 函数中。
像上面的答案一样配置 SECURE_PROXY_SSL_HEADER https://stackoverflow.com/a/72685575/1611526
class BothHttpAndHttpsSchemaGenerator(OpenAPISchemaGenerator):
def get_schema(self, request=None, public=False):
schema = super().get_schema(request, public)
if request.is_secure():
schema.schemes = ['https']
else:
schema.schemes = ['http']
return schema
然后:
schema_view = get_schema_view(
...
generator_class=BothHttpAndHttpsSchemaGenerator,
)
此配置适用于开发和生产环境。