CreateCustomToken() 通过 Firebase Auth Emulator 在 JWT 令牌中有“alg”:“none”,使其无法通过 Firebase Admin SDK 或自定义 JWT Verifier 验证

问题描述 投票:0回答:0

上下文:

我正在使用带有 Firebase Admin SDK 的节点云功能来创建自定义令牌(在本地测试时通过模拟器)。 该令牌被发送到 React 应用程序,在那里它被使用并转换为 IdToken。 然后该令牌被尝试用作 Golang REST 服务器的身份验证令牌,我正在尝试使用 Firebase Admin SDK 对其进行验证

问题:

出于一些超出我推理的奇怪原因,每当我尝试通过本地仿真云函数内的本地 Auth 模拟器生成自定义 firebase 令牌时,

"alg"
的标头似乎总是
"none"
。部署函数时不是这样

令牌生成示例代码:

admin.auth().createCustomToken(request.body.username...

下面的截图代表了TokenId解码后的内容(使用生成的token登录,从获取的用户调用

.getIdToken()
获取)

这个特定的 ID 令牌,在有效负载中缺少“kid”标头,使其无法对抗 Golang Admin SDK 中的

VerifyIDTokenAndCheckRevoked()
(已尝试)。

并且也会被自定义的 JWT 验证器失效,因为“alg”是

none
,默认情况下它是不允许的。 (表示错误:
token is unverifiable: 'none' signature type is not allowed
) 以下代码代表自定义验证器:

func (s *authService) VerifyToken(ctx context.Context, token string) (*CustomClaims, error) {
    var customClaims *CustomClaims

    parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
        // It doesn't work even with this validation commented...
        if val, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
            return nil, fmt.Errorf("> Wrong signing method: %v", token.Method.Alg())
        } else {
            if val.Alg() != "RS256" {
                return nil, fmt.Errorf("> Unexpected signing method: %v", val.Alg())
            }
        }

        // In order to be able to decode the token manually, we need to give the private key to the Parse function
        hmacSecret := []byte(os.Getenv("FIREBASE_CREDENTIALS_PRIVATE_KEY"))
        return hmacSecret, nil
    })
    if err != nil {
        if errors.Is(err, jwt.ErrTokenMalformed) {
            return nil, fmt.Errorf("> Malformed authentication: %s", err.Error())
        } else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
            return nil, fmt.Errorf("> Expired authentication token: %s", err.Error())
        } else {
            return nil, fmt.Errorf("> Something is wrong with the authentication: %s", err.Error())
        }
    }

    if claims, ok := parsedToken.Claims.(jwt.MapClaims); ok && parsedToken.Valid {
        byteClaims, err := json.Marshal(claims)
        if err != nil {
            return nil, err
        }

        err = json.Unmarshal(byteClaims, customClaims)
        if err != nil {
            return nil, err
        }

        return customClaims, nil

    }
    
    return nil, fmt.Errorf("> Something is wrong with the authentication claims")
    

    /* Deprecated method due to custom token verification issue (no kid header) with Admin SDK*/
    // client, err := s.app.Auth(ctx)
    // if err != nil {
    //  return nil, err
    // }

    // authToken, err := client.VerifyIDTokenAndCheckRevoked(ctx, token)
    // if err != nil {
    //  return nil, err
    // }

}

这个阻塞有什么解决方法吗?

也许允许模拟器使用正确的“alg”标头对令牌进行签名,或者可能跳过自定义 JWT 验证程序中的“alg”验证?

我看过另一个类似的问题,但没有解决方案: Firebase createCustomToken() 在本地模拟器中返回无效令牌

node.js firebase go firebase-authentication jwt
© www.soinside.com 2019 - 2024. All rights reserved.