公司新上线了一套内部订单系统,开发组把 API 文档托管在 Swagger UI 上,结果市场部同事点开链接,直接看到所有接口路径、参数和数据库字段名,连「/api/v1/user/delete」这种高危接口都明晃晃列着——还好没人乱点。
权限不是摆设,是门槛
API 文档不是“公开说明书”,它本质是一份技术契约,面向的是调用方(比如前端、第三方合作方、测试同学),不是所有人。开放无限制的文档访问,等于把钥匙串挂门口——看着方便,但风险藏得深。
常见权限控制方式
多数团队用这几种组合来管文档门禁:
- 登录态拦截:不登录看不到页面,比如用企业微信扫码或统一账号登录后才加载文档内容;
- 角色分组授权:后台配置「开发组可读写」、「测试组只读」、「外部合作方仅查看指定模块」;
- 静态文档拆分:把完整 OpenAPI YAML 拆成多个文件,用 Nginx 或 GitHub Pages 做路径级权限,比如
/docs/internal/403,/docs/public/公开; - 网关层过滤:在 API 网关(如 Kong、APISIX)加规则,对
/swagger.json请求按 IP 段或 Header 中的 token 鉴权。
一个实操小例子
你用的是 Swagger UI + Spring Boot,想让内网员工能看,外网访客 404:
@Configuration
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.api"))
.paths(PathSelectors.any())
.build()
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Arrays.asList(apiKey()));
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/api/.*"))
.build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] scopes = new AuthorizationScope[]{authorizationScope};
return Arrays.asList(new SecurityReference("apiKey", scopes));
}
private ApiKey apiKey() {
return new ApiKey("apiKey", "X-API-KEY", "header");
}
}再配合一个简单的拦截器,校验请求头里的 X-API-KEY 是否匹配内网白名单,或者是否来自 192.168.0.0/16 网段,就能卡住大部分非授权访问。
别忘了文档本身也得“脱敏”
权限设好了,还得检查文档内容:示例响应里有没有真实手机号、身份证号、token 字段?错误提示里有没有暴露数据库表名或 SQL 片段?这些细节,比权限开关更早泄露风险。
文档不是越全越好,而是够用、安全、对的人看得懂。改一次配置,少一次救火。