在 go 中验证 google 条聊天机器人消息

Verify google chat bot messages in go

我正在尝试创建一个 google 聊天机器人,它通过 google 聊天接收一些 post 并将数据发送到电子表格。所有这些都工作正常,但我正在努力进行身份验证。

我遵循提供的文档 here 并尝试翻译功能。不幸的是,我惨遭失败。 ;-D

我做了什么?

我用"github.com/coreos/go-oidc"来运行验证。

像这样设置验证器:

const (
    audience            string = "my-project-id"
    publicCertUrlPrefix string = "https://www.googleapis.com/service_accounts/v1/metadata/x509/"
    chatIssuer          string = "chat@system.gserviceaccount.com"
)

func init() {
    context = cnx.Background()
    keySet := oidc.NewRemoteKeySet(context, publicCertUrlPrefix+chatIssuer)
    config := &oidc.Config{
        SkipClientIDCheck: true,
        ClientID:          audience,
    }
    verifier = oidc.NewVerifier(chatIssuer, keySet, config)
}

并尝试运行验证:

func VerifyToken(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        // no authorization for health endpoint
        if r.URL.Path == "/health" {
            next.ServeHTTP(w, r)
            return
        }

        authHeader := r.Header.Get("Authorization")
        if authHeader == "" {
            logger.Debug("No authorization header is provided")
            http.Error(w, "Forbidden", http.StatusForbidden)
            return
        }

        authHeaderParts := strings.Fields(authHeader)
        if len(authHeaderParts) != 2 || strings.ToLower(authHeaderParts[0]) != "bearer" {
            logger.Debug("Authorization header is not valid")
            http.Error(w, "Authorization header format must be Bearer {token}", http.StatusForbidden)
            return
        }

        token := authHeaderParts[1]
        if _, e := verifier.Verify(context, token); e != nil {
            logger.Debug("Invalid token: ", e.Error())
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }

        next.ServeHTTP(w, r)
    })
}

不幸的是,失败并出现以下错误:

Invalid token: failed to verify signature: failed to verify id token signature

知道我做错了什么吗?

最佳

所以我们通过为密钥设置正确的 URL 来让它工作,因为我们期待一个 jwt 令牌,URL 必须是:https://www.googleapis.com/service_accounts/v1/jwk/

const (
    audience            string = "my-project-id"
    jwtURL              string = "https://www.googleapis.com/service_accounts/v1/jwk/"
    chatIssuer          string = "chat@system.gserviceaccount.com"
)

func init() {
    context = cnx.Background()
    keySet := oidc.NewRemoteKeySet(context, jwtURL+chatIssuer)
    config := &oidc.Config{
        SkipClientIDCheck: true,
        ClientID:          audience,
    }
    verifier = oidc.NewVerifier(chatIssuer, keySet, config)
}