Golang使用Go-swagger实现认证功能的完整指南

Golang使用Go-swagger实现认证功能的完整指南 我正在尝试使用 Swagger 为我的 API 实现身份验证。我参考了这里的示例:使用 API 密钥进行身份验证 | go-swagger

consumes:
- application/json
info:
  description: myapi
  title: myapi
  version: 3.0.0
produces:
- application/json
schemes:
- http
swagger: "2.0"
parameters:
  xxx
securityDefinitions:
  SecretAuth:
    type: apiKey
    name: MyToken
    in: header
    description: "输入令牌"
security:
   - SecretAuth: []
paths:

这是 Go 语言中的 API 定义:

func configureAPI(api *operations.RestAPI) http.Handler {

	api.ServeError = errors.ServeError

	api.UseSwaggerUI()

	api.JSONConsumer = runtime.JSONConsumer()

	api.JSONProducer = runtime.JSONProducer()
	api.TxtProducer = runtime.TextProducer()

	// 当设置了 "MyToken" 请求头时应用
	api.SecretAuthAuth = func(token string) (*models.Principal, error) {
		if token == xxxx {
			prin := models.Principal(token)
			return &prin, nil
		}
		api.Logger("使用错误的 API 密钥尝试访问: %s", token)
		return nil, errors.New(401, "错误的 API 密钥")
	}

.
.
.
<rest-of-the-code>

问题是,当我调用 API 端点时,身份验证被忽略了:

curl -v --insecure \
  -X GET \
  -H "Content-Type: application/json" \
  -H "Authentication: MyToken xxx" \
  https://MacBook-Pro.local:12443/compliance/api/v1/state

对于我做错了什么,有什么建议吗?

我认为 MyToken 的值就是自动传递给 api.SecretAuthAuth 函数的值(即 token 参数)。


更多关于Golang使用Go-swagger实现认证功能的完整指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

啊,API认证的艺术——一场数字之舞,每个令牌都必须完美同步!

更多关于Golang使用Go-swagger实现认证功能的完整指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


根据你的描述,问题在于请求头名称不匹配。在Swagger定义中,你指定了name: MyToken,这意味着认证头应该是MyToken,但你实际发送的是Authentication头。

以下是修正后的curl命令:

curl -v --insecure \
  -X GET \
  -H "Content-Type: application/json" \
  -H "MyToken: xxx" \
  https://MacBook-Pro.local:12443/compliance/api/v1/state

另外,确保你的Swagger定义正确配置了安全要求。在paths部分,需要为每个端点明确指定安全要求:

paths:
  /compliance/api/v1/state:
    get:
      security:
        - SecretAuth: []
      responses:
        200:
          description: Success

在Go代码中,认证函数应该这样实现:

api.SecretAuthAuth = func(token string) (*models.Principal, error) {
    // 这里应该是实际的令牌验证逻辑
    if token == "valid-token-value" {
        prin := models.Principal(token)
        return &prin, nil
    }
    api.Logger("无效的API密钥: %s", token)
    return nil, errors.New(401, "无效的API密钥")
}

如果问题仍然存在,可以添加调试日志来验证认证函数是否被调用:

api.SecretAuthAuth = func(token string) (*models.Principal, error) {
    api.Logger("认证函数被调用,令牌: %s", token)
    
    if token == "valid-token-value" {
        prin := models.Principal(token)
        return &prin, nil
    }
    api.Logger("无效的API密钥: %s", token)
    return nil, errors.New(401, "无效的API密钥")
}
回到顶部