Firebase身份验证ID令牌不正确" aud"要求

时间:2016-07-12 17:09:01

标签: node.js firebase firebase-authentication

我正在尝试验证idToken后端。用户已成功登录到firebase客户端,但当我尝试验证后端的idToken时,我得到的这个不是非常有用的错误消息

  

Firebase身份验证ID令牌不正确" aud"根据权利要求

错误消息似乎变得更有用,并且归结为在auth密钥中没有项目名称:

  

错误:Firebase ID令牌不正确" aud" (观众)声称。   预期" stripmall-0000"但得到了   " 617699194096-0aafcvsml0gke61d6077kkark051f3e1.apps.googleusercontent.com&#34 ;.   确保ID令牌来自与此相同的Firebase项目   用于验证此SDK的服务帐户。看到   https://firebase.google.com/docs/auth/server/verify-id-tokens   有关如何检索ID令牌的详细信息。

任何有丝毫想法可能出错的人?我从客户端正确地收到了tokenId,因此不应该成为问题。真诚的应用,如果之前已经被问过,或者以任何其他方式是微不足道的。

  firebase.initializeApp({
        serviceAccount: {
            "type": "service_account",
            "project_id": <project id here>,
            "private_key_id": <key id goes here>,
            "private_key": <key goes here>
            "client_email": <email goes here>,
            "client_id": <my client id>,
            "auth_uri": "https://accounts.google.com/o/oauth2/auth",
            "token_uri": "https://accounts.google.com/o/oauth2/token",
            "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
            "client_x509_cert_url": <url goes here>
        },
        databaseURL: <my db url here>
    });

    router.post("/verify", function (req, res) {
        firebase.auth().verifyIdToken(req.body.idToken).then(function (decodedToken) {
            var uid = decodedToken.sub;
            res.send(uid);
        }).catch(function (error, param2) {
            console.log(error);  // 'Firebase Auth ID token has incorrect "aud" claim'
        });

    });

7 个答案:

答案 0 :(得分:16)

您的问题可能是您尝试使用其中一个auth()函数返回的JWT令牌,例如firebaseRef.auth().signInWithPopup()。这些确实会返回JWT令牌,但是身份验证声明可能会出错,并且无法通过verifyIdToken验证。这得到了firebase技术支持的证实。

您必须使用firebaseRef.auth().currentUser.getToken()功能。该令牌将通过验证。

答案 1 :(得分:1)

我的问题是令牌,但我需要使用服务帐户初始化我的后端。这样做,您也可以从本地开发服务器进行测试和调试。

FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");

FirebaseOptions options = new FirebaseOptions.Builder()
            .setCredentials(GoogleCredentials.fromStream(serviceAccount))
            .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
            .build();

FirebaseApp.initializeApp(options);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();

// Get the FB uid from the token
FirebaseToken decodedToken = firebaseAuth.verifyIdTokenAsync(token).get();
String uid = decodedToken.getUid();

来源:nan

答案 2 :(得分:0)

如果您在本地运行,如果您的GOOGLE_APPLICATION_CREDENTIALS环境变量不正确,也会弹出此错误消息。检查使用此环境变量设置的JSON密钥是否与项目的JSON密钥匹配。

答案 3 :(得分:0)

TLDR:如另一个答案所述,您没有正确初始化应用程序。

尽管我在这个问题上有点迟了,但是我遇到了同样的问题,所以我决定深入研究一下引擎盖后面的情况。

首先,除非自提出此问题以来API发生更改,否则serviceAccount作为AppOptions接口一部分的属性不存在,这可能就是您收到错误的原因。因此,我假设您在credential键中拥有的含义。

第二,您看到此错误引发于https://github.com/firebase/firebase-admin-node/blob/master/src/auth/token-verifier.ts(在撰写本文时为第187行),其中令牌中的aud声明与this.projectId进行了比较。

现在,如其他答案所述,这可能是因为您要验证的令牌不是在客户端创建的,而是通过其他自定义方法创建的,在这种情况下,aud声明可能不是存在,完全随机的事物或绝对不等于您的projectId的事物,因此您应该先进行检查。

但是,如果您确定令牌是在客户端创建的,则可以归结为projectId未被设置,或者至少没有按照您期望的方式被设置。如果查看https://github.com/firebase/firebase-admin-node/blob/master/src/utils/index.ts中的getProjectId()方法(在撰写本文时,是第66行),您会发现projectId是通过以下三种方式之一确定的:从{{1 }}直接从app.options的{​​{1}}属性中获得对象,或者从projectId中获得。这意味着,如果未设置app.options.credential,并且您的项目托管在GCloud上(我假设是process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT),那么Google会自动将您当前环境的projectId用于与firebase相关的任何操作, auth,而不是原始项目的projectId。

因此,有三个选择:

  1. 使用直接在projectId中设置的stripmall-0000初始化应用程序:

    projectId
  2. 或者通过适当设置凭据对象来实现此目的可能更好:

    AppOptions
  3. 或者,仅将应用程序托管在与您的Firebase应用程序相同的项目中(现在它们是同一生态系统的一部分),以便环境变量相同。 (实际上不是100%,但这是Firebase函数又称云函数的工作原理)

答案 4 :(得分:0)

还有另一种情况会产生这种令人沮丧的错误。如果您打开了诸如Postman,Insomnia,GraphQL Playground(这次罪魁祸首)之类的查询工具,则这些工具可能持有旧的Authentication Bearer令牌并向您的API发出请求,即使您的身份验证密钥已更改。 / p>

这里的简单解决方案是清除当前已使用这些Bearer令牌进行身份验证的所有请求,然后重新进行身份验证。

这对于GraphQL Playground尤其讨厌,因为它的基本性质迫使您将auth令牌复制/粘贴到每个查询选项卡的标题中,因此,如果您不关闭或修改每个选项卡,您仍将收到此错误,将您的API控制台发送垃圾邮件。

我建议使用Insomnia作为其解毒剂,因为采用适当的查询链接做法,您完全可以避免这种情况。进一步的细节:您可以通过Insomnia的环境变量之一将用户身份验证查询的承载令牌结果自动传递给任何其他查询。

答案 5 :(得分:0)

如Thach Lockevn在评论中所述 对我有用的解决方案是:

import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';

this.angularFireAuth.signInWithPopup(new auth.GoogleAuthProvider()).then((googleAuth) => {
        this.user = googleAuth.user;
        googleAuth.user.getIdToken().then(tkn => {
            this.token = tkn;
            //send the token to the backend...
        });
    });

答案 6 :(得分:0)

错误的受众(错误的项目 GOOGLE 项目之间的冲突 FIX)

我在 GKE 集群中使用 NetJS 服务器(使用帐户 A 创建),并尝试将管理 SDK 连接到外部 Firebase 应用(使用帐户 B 创建)。

<块引用>

GKE 正在使用影响 NextJS 应用的环境变量设置凭据

解决方案

我为 NextJS 应用程序设置了 GOOGLE_APPLICATION_CREDENTIALS 环境(您可以使用 .env 文件。

结论

Node 变量的优先级高于默认的 auth 应用程序(疯了!)

https://firebase.google.com/docs/admin/setup#initialize_the_sdk