首页 > 解决方案 > 在创建用于生成 Firebase CustomToken 的服务器时,我是仅使用服务帐户还是在幕后使用用户凭据?

问题描述

我们很快将这个项目投入生产。

1 - 我们的移动应用程序将通过将其发布到我们的内部微服务来创建汇款。这样的 post 请求将返回从我们的内部 NodeJs 服务器生成的 CustomToken。

2 - 我们的内部微服务会将此类传输复制到 Firestore 并相应地更新其在 Firestore 上的状态。

3 - 代替我们的移动应用程序轮询或侦听我们的内部微服务以获取状态,它将侦听 Firestore 以从相应文档中获取状态。为了收听,它将使用步骤 1 中从 post 返回的 CustomToken。我们公司只想利用 Google Firestore 的实时数据库功能用于该项目(反应式方法)。

与我对以下声明所做的比较时,您是否看到任何考虑/问题:“Google 在大多数情况下更喜欢您授权使用服务帐户”?(复制自其他相关讨论

CustomToken 是在此 NodeJs 服务器内部创建的,并且取决于从 Google Firebase 的预授权用户身份验证/用户中提取的 uid

    const admin = require('firebase-admin');

    exports.serviceAccount = {
      "type": "service_account",
      "project_id": "firetestjimis",
      "private_key_id": "ecfc6 ... fd05923",
      "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE .... 5EKvQ==\n-----END PRIVATE KEY-----\n",
      "client_email": "firebase-adminsdk-fg6p9@firetestjimis.iam.gserviceaccount.com",
      "client_id": "102422819688924138150",
      "auth_uri": "https://accounts.google.com/o/oauth2/auth",
      "token_uri": "https://oauth2.googleapis.com/token",
      "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
      "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fg6p9%40firetestjimis.iam.gserviceaccount.com"
    }

     admin.initializeApp({
       credential: admin.credential.cert(exports.serviceAccount)
    });


var uid = "NS .... Ro2"; //copied from https://console.firebase.google.com/project/firetestjimis/authentication/users
var claim = {
  control: true
};
admin.auth().createCustomToken(uid)
  .then(function (customToken) {
    console.log(customToken)
  })
  .catch(function (error) {
    console.log("Error creating custom token:", error);
  });

我们的手机(Angular 中的示例,但 IOS 和 Android 的想法相同)具有我下载的 SERVICE_ACCOUNT_JSON_FILE,如下所示:

环境.ts:

export const environment = {
  production: false,
  firebaseConfig: {
    apiKey: "AIzaSy ... 3DCGihK3xs",
    authDomain: "firetestjimis.firebaseapp.com",
    databaseURL: "https://firetestjimis.firebaseio.com",
    projectId: "firetestjimis",
    storageBucket: "firetestjimis.appspot.com",
    messagingSenderId: "795318872350",
    appId: "1:7953 ... 32b26fb53dc810f"
  }
};

app.component.ts

  public transfers: Observable<any[]>;

  transferCollectionRef: AngularFirestoreCollection<any>;

  constructor(public auth: AngularFireAuth, public db: AngularFirestore) {
    this.listenSingleTransferWithToken();
  }

  async listenSingleTransferWithToken() {
    await this.auth.signInWithCustomToken("eyJh ### CUSTOMTOKEN GENERATED FROM INTERNAL NODEJS SERVER ABOVE ### CVg");
    this.transferCollectionRef = this.db.collection<any>('transfer', ref => ref.where("id", "==", "1"));
    this.transfers = this.transferCollectionRef.snapshotChanges().map(actions => {
      return actions.map(action => {
        const data = action.payload.doc.data();
        const id = action.payload.doc.id;
        return { id, ...data };
      });
    });
  }
}

我了解 CustomToken 创建及其在我们的移动设备中的使用都完全依赖于服务帐户。我对吗?我是否错过了一些概念,并且我在幕后使用了 USER CREDENTIAL 并且在 DEV 环境中正常工作的东西在生产时会弹出一些惊喜?显然,对于这个问题,所有问题都来自我的免费帐户,但在生产中它将是付费帐户,但代码和步骤在这里完全相同。

*** 在约翰的评论之后编辑

事实上 environment.ts 去浏览器。如果有问题,也许有听 Firestore 文档经验的 Angular 开发人员可以发表评论

环境.ts

标签: javascriptfirebasegoogle-cloud-firestorefirebase-authenticationfirebase-admin

解决方案


据我所知,您当前创建自定义的方式纯粹基于服务帐户,以及您对用户 UID(您从控制台复制的 UID)的隐含知识。据我所知,您共享的代码中没有其他用户凭据,流程的其他部分也没有。

不过,我很想知道您是如何保护此令牌生成的:是什么阻止了任何其他 Web 客户端调用您的listenSingleTransferWithToken方法或以其他方式从数据库中读取令牌?


推荐阅读