說明: 本文由 AI(Claude Sonnet 4.6)根據我的初始筆記與想法完成。
在 Metis 後端用 Go 驗證 Firebase ID Token 時,踩了一個坑:公鑰必須先 parse 過才能使用,否則會拋出 key is of invalid type。
Firebase 的 ID Token 是一個 RSA 簽名的 JWT。驗證時需要:
kid 選對應的公鑰從 Google 拿回來的公鑰是 PEM 格式的字串。如果直接把字串傳進 jwt.ParseWithClaims 的 keyfunc,就會拿到這個錯誤:
key is of invalid type
golang-jwt/jwt 預期的是 *rsa.PublicKey,不是原始字串。
在 keyfunc 裡,取到 PEM 字串之後,要先呼叫 jwt.ParseRSAPublicKeyFromPEM() 轉成 *rsa.PublicKey 再回傳:
token, err := jwt.ParseWithClaims(rawToken, &claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
keys, err := google.GetKeys(httpClient).Execute()
if err != nil {
return nil, err
}
kid := fmt.Sprintf("%s", token.Header["kid"])
publicKey := fmt.Sprintf("%s", keys[kid])
// 這步不能少:PEM 字串要 parse 成 *rsa.PublicKey
parsedKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
if err != nil {
return nil, err
}
return parsedKey, nil
})
少了 ParseRSAPublicKeyFromPEM,直接 return publicKey, nil 就是 key is of invalid type 的根源。