Python|fastapi之隐藏docs(安全初探)(三)

fastapi开发api确实fast.东西开发完了,前后端调试也方便,要上线了,怎么保证接口文档不被非法访问呢?简单想了几个场景

内网部署

将swagger的入口监听在内网,域名访问的话,也直接解析成内网,外网不能访问也是个不错的选择.

直接关闭

这招算是釜底抽薪了,直接关门,咱都不访问.算是最简单有效的办法.
代码

app = FastAPI(
    docs_url=None,
    redoc_url=None
)

动态开关

默认关闭,确实有需要查看,临时打开,用完关闭,也是个不错的选择.
原理就是:访问/docs时,默认没有,通过另一个接口临时调整一个参数,这时才允许访问.
主要代码

app = FastAPI(
    docs_url=None,
    redoc_url=None
)
@app.get('/add_docs')
def show_docs_by_manager():
    logger.info(app.docs_url)
    msg = 'ok'
    if app.docs_url is None:
        app.docs_url = '/docs'
        msg = 'docs is open !'
    else:
        app.docs_url = None
        msg = 'docs is disabled !'
    logger.info(app.docs_url)
    return response_struct(msg=msg)
@app.get("/docs")
async def get_documentation():
    if app.docs_url is None:
        return response_struct()
    else:
        return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")

如上,需要访问时,直接/add_docs接口,也不添加参数了,访问一次打开,再访问一次关闭,这样就实现了动态开关的目的.

开启basic auth

出发点就是访问/docs时进行一次用户名和密码认证,用nginx的话很容易实现
示例代码

echo "username:$(openssl passwd -crypt 'password')" >> /home/.htpasswd

location /docs {
    auth_basic  "请输入密码";
    auth_basic_user_file /etc/apache2/.htpasswd; 
}

既然nginx能实现,我牛掰fastapi自然也可以.
代码

from fastapi import Depends, FastAPI, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from starlette.status import HTTP_401_UNAUTHORIZED
from fastapi.openapi.docs import get_swagger_ui_html
app = FastAPI(
    docs_url=None
)

security = HTTPBasic()

@app.get("/docs",include_in_schema=False)
async def get_documentation(credentials: HTTPBasicCredentials = Depends(security)):
    if credentials.username != "rainbird" or credentials.password != "pwd":
        raise HTTPException(
            status_code=HTTP_401_UNAUTHORIZED,
            detail="Incorrect email or password",
            headers={"WWW-Authenticate": "Basic"},
        )
    else:
        return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")

Python|fastapi之隐藏docs(安全初探)(三)
如上,访问/docs需要验证,用户名是rainbird,密码是pwd

结尾

本文只是简单的示范了swagger的页面安全问题.对于后端接口,内部访问的话最好就是直接放内网,也不需要加密和认证,性能会好一些.如果接口一定要放公网的话,除了考虑好swagger的安全,还要处理好接口的访问权限,切莫要门户大开,锁都不加.

上一篇:waypoint 参考架构


下一篇:Vue -- Popover 简单实践 & 如何通过点击按钮关闭 Popover 弹出框