最彻底禁用文档的方式是初始化fastapi时将docs_url、redoc_url、openapi_url均设为none;按环境动态开关需统一控制三项;加basic auth须同步保护/docs和/openapi.json;隐藏单个接口用include_in_schema=false;关文档不等于关api,权限仍需中间件保障。

直接禁用 docs、redoc 和 openapi.json 三个入口
最彻底的方式,就是在初始化 FastAPI 实例时把三个关键 URL 全部设为 None。这样连文档页面、ReDoc 页面和 OpenAPI JSON 文件都不可访问,不依赖中间件或环境判断,无死角屏蔽:
from fastapi import FastAPI <p>app = FastAPI( docs_url=None, # 禁用 /docs redoc_url=None, # 禁用 /redoc openapi_url=None # 禁用 /openapi.json )</p>
注意:openapi_url=None 是关键一环。只关 /docs 而不关 /openapi.json,攻击者仍可手动请求该文件拿到完整接口契约,再用本地 Swagger UI 渲染——等于白关。
按环境动态开关文档(推荐用于多环境部署)
多数项目需要开发/测试环境开着文档、生产环境关掉。靠环境变量控制比硬编码更安全,也避免误提交配置。常见错误是只判断 ENV == "production" 就关,但漏掉 testing 场景;或者忘了同步关掉 openapi_url:
- 在
.env中定义ENV=production(或development、testing) - 读取后用布尔值控制开关,而非字符串比较嵌套在
FastAPI()参数里 - 务必统一关掉
docs_url、redoc_url、openapi_url三项
示例逻辑:
IS_DEV = ENV in ("development", "testing")
<p>app = FastAPI(
docs_url="/docs" if IS_DEV else None,
redoc_url="/redoc" if IS_DEV else None,
openapi_url="/openapi.json" if IS_DEV else None,
)</p>
保留文档但加 Basic Auth 访问控制
有些团队希望生产环境也能有限度地开放文档(比如给运维或内部 QA),又不想暴露给所有人。这时不能只靠前端路由拦截,必须在服务端做认证。常见坑是:用普通字符串比较校验密码(引发计时攻击)、没对 /openapi.json 同步加锁、静态资源路径写错导致 404:
- 必须用
secrets.compare_digest()校验账号密码 -
/docs和/openapi.json都要挂上同一个依赖函数 -
get_swagger_ui_html()中的swagger_js_url、swagger_css_url必须带正确前缀(如/static/...),否则浏览器会去根路径加载失败
片段示意:
@app.get("/docs", include_in_schema=False)
async def get_docs(username: str = Depends(datetime_verify_docs)):
return get_swagger_ui_html(
openapi_url="/openapi.json",
swagger_js_url="/static/swagger/swagger-ui-bundle.js",
swagger_css_url="/static/swagger/swagger-ui.css",
)
<p>@app.get("/openapi.json", include_in_schema=False)
async def get_openapi_json(username: str = Depends(datetime_verify_docs)):
return get_openapi(...)
</p>
隐藏单个接口,而不是整个文档
如果只是想让某个管理类接口(比如 /admin/export)不出现在文档里,不需要关整站文档。用 include_in_schema=False 即可,它只影响 OpenAPI 生成逻辑,不影响路由本身是否可访问:
@app.get("/admin/export", include_in_schema=False)
def export_data():
return {"status": "done"}
这个参数对所有路径操作装饰器都有效,包括 @app.post、@app.put 等。注意它和 response_model_exclude_unset 这类响应控制参数无关,别混淆。
真正容易被忽略的是:关文档 ≠ 关 API。即使 /docs 和 /openapi.json 都禁用了,只要路由还注册着,接口就依然能被调用。安全边界得靠权限中间件或网关层控制,不是靠藏文档实现的。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











