Swagger 2.0中如何允许security参数(apiKey)接受空值或Null?
问题:Swagger认证配置无法允许user_id为空/nil
期望的验证逻辑
- 收到token,无user_id:成功
- 收到token,有user_id:成功
- 无token,有user_id:失败
- 无token,无user_id:失败
当前Swagger安全定义
securityDefinitions: BearerToken: type: apiKey in: header name: authorization UserId: type: apiKey in: header name: user_id
当前API安全配置
security: - BearerToken: [] UserId: [] - ServiceAPIKey: []
当前实现现状
- 收到token,无user_id:失败(需改为成功)
- 收到token,有user_id:已实现
- 无token,有user_id:已实现
- 无token,无user_id:已实现
尝试过的调整
曾修改security的AND/OR逻辑,也尝试添加单独的BearerToken配置,但问题依旧:
security: - BearerToken: [] UserId: [] - ServiceAPIKey: [] - BearerToken: []
处理层代码
// service auth handler handler.BearerTokenAuth = func(token string) (interface{}, error) { authToken = token authPrincipal, err := rt.Client().AuthenticateRequest(token, http.MethodGet, "", "") if err != nil { return nil, errors.New(401, "invalid bearer token") } return authPrincipal, nil } // service auth handler handler.UserIDAuth = func(userId string) (interface{}, error) { authPrincipal, err := rt.Client().AuthenticateRequest(authToken, http.MethodGet, "", userId) if err != nil { return nil, errors.New(401, "invalid user id") } return authPrincipal, nil }
解决方案
1. 调整Swagger的security配置
Swagger的security规则里,同一个数组元素内的认证方式是AND关系,不同元素是OR关系。要实现“BearerToken可选带UserId”,得把两种情况拆成两个OR项:
security: # 情况1:携带BearerToken + UserId(同时校验) - BearerToken: [] UserId: [] # 情况2:仅携带BearerToken(跳过UserId校验) - BearerToken: [] # 保留原有ServiceAPIKey认证方式 - ServiceAPIKey: []
这样配置后,请求满足任意一种规则就能通过认证。
2. 修改UserId认证Handler逻辑
当前Handler在userId为空时会直接调用校验接口导致失败,需要先判断userId是否为空,为空则直接通过(此时已经过BearerToken校验):
handler.UserIDAuth = func(userId string) (interface{}, error) { // userId为空时直接通过,复用BearerToken校验后的主体信息 if userId == "" { return authPrincipal, nil } // userId不为空时执行原有校验逻辑 authPrincipal, err := rt.Client().AuthenticateRequest(authToken, http.MethodGet, "", userId) if err != nil { return nil, errors.New(401, "invalid user id") } return authPrincipal, nil }
注意:要确保authPrincipal在BearerToken校验时已正确赋值且可访问,也可以通过上下文传递该对象。
3. 验证逻辑说明
- 带BearerToken但无UserId:匹配
- BearerToken: []规则,跳过UserId校验,返回成功 - 带BearerToken和UserId:匹配
- BearerToken: []\n UserId: []规则,同时校验两者,符合条件则成功 - 无Token的情况:无法匹配任何规则,直接返回401,符合预期
内容的提问来源于stack exchange,提问作者shezzy7
相关产品推荐
相关产品推荐

