一,代码:
说明:
如果生产环境中确实需要让外部客户或内部运营人员查看文档,但又不能公开,加上“用户名/密码”是最轻量高效的方案。
FastAPI 本身并没有给 /docs 内置开关,但我们可以通过关闭默认路由,改为手动重写 docs 接口并注入安全依赖来实现。
效果: 任何人访问 /docs 时,浏览器会自动弹出一个原生的输入框要求输入账号密码,只有验证通过才能看到文档。
# 创建FastAPI应用,并传入 lifespan
# 1. 初始化时禁用默认的 docs 路由
api_app = FastAPI(title="我的API项目",docs_url=None, redoc_url=None, openapi_url=None)security = HTTPBasic()# 2. 账号密码校验函数
def datetime_verify_docs(credentials: HTTPBasicCredentials = Depends(security)):# 使用 secrets.compare_digest 防范计时攻击 (Timing Attacks)correct_username = secrets.compare_digest(credentials.username, "admin")correct_password = secrets.compare_digest(credentials.password, "123456")if not (correct_username and correct_password):raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,detail="用户名或密码错误",headers={"WWW-Authenticate": "Basic"},)return credentials.username# 3. 手动重写 /openapi.json 并加锁
@api_app.get("/openapi.json", include_in_schema=False)
async def get_open_api_endpoint(username: str = Depends(datetime_verify_docs)):return get_openapi(title=api_app.title, version=api_app.version, routes=api_app.routes)# 4. 手动重写 /docs 并加锁
@api_app.get("/docs", include_in_schema=False)
async def get_documentation(username: str = Depends(datetime_verify_docs)):return get_swagger_ui_html(openapi_url="/api/openapi.json",title=api_app.title + " - Docs",# 【核心修正 3】:静态资源路径也必须拼接 root_path,否则会去根目录下找,导致404或找错swagger_js_url=f"/static/swagger/swagger-ui-bundle.js",swagger_css_url=f"/static/swagger/swagger-ui.css",swagger_favicon_url=f"/static/swagger/favicon.png")
二,测试效果:

