【问题标题】:Which firebase value from firebase-auth to use as uid in my own database?firebase-auth 中的哪个 firebase 值在我自己的数据库中用作 uid?
【发布时间】:2020-12-18 08:43:37
【问题描述】:

我正在使用 Firebase 身份验证,我需要将经过身份验证的用户存储在我自己的用户表中(我只打算使用 firebase 身份验证,而不是他们的后端服务)。但是,我不确定应该使用 firebase 提供的哪个值作为唯一标识符。

在文档中,Firebase 指出:

 uid = user.uid;  // The user's ID, unique to the Firebase project. Do NOT use
                   // this value to authenticate with your backend server, if
                   // you have one. Use User.getToken() instead.

根据上面的评论(见此处:https://firebase.google.com/docs/auth/web/manage-users),这意味着我不能依赖uid

他们是说我应该使用

 user.getIdToken().then((token) => {
  // is this my UUID that I should store in my own db
  // this one? Its 926 characters long, 
  console.log(token);
 });

【问题讨论】:

  • 值得一提的是,尽管您可能不想使用其他一些 Firebase 产品,但您可能会发现在 Google Cloud Platform 范围内托管您的服务以帮助减少身份验证时的网络延迟会更高效到您的后端。 IMO Cloud Run 对于 API 来说是特别好的产品,并且与 Firebase Auth 配合得非常好。
  • ELI5?不知道more performant to host your service within the realm of the Google Cloud Platform to help reduce network latency是什么意思@什么服务?
  • 我假设您有一个您对其进行身份验证的前端应用程序。由于您选择不使用 Firebase 函数或直接从客户端应用调用 Firestore,您需要通过其他方式提供一些后端功能,通常使用 API 服务?
  • 是的。我计划在后端使用 Django(作为我的 nuxt 前端的 rest api)和 Postgres db。我转向 firebase 的唯一原因是因为 SPA 上的身份验证很难设置 IMO
  • 我使用 JavaScript 编写了答案,因为这是问题中唯一可用的标签。您需要调整以下示例以在服务器端代码 firebase.google.com/docs/reference/admin/python/… 上使用 Python 等效项

标签: javascript firebase-authentication


【解决方案1】:

使用 Firebase Auth user.uid 键入您自己的用户表。

客户端:

您的网络应用程序在最终用户的浏览器中运行,并使用 Firebase 客户端 SDK。例如,电子邮件和密码登录可能如下所示:

firebase.auth().signInWithEmailAndPassword(email, password)
  .then((user) => {
    // Signed in 
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
  });

https://firebase.google.com/docs/auth/web/start#sign_in_existing_users

浏览器在后台从 Firebase 身份验证服务获取 JWT。令牌每小时更新一次,您可以使用事件侦听器获取这些令牌。

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    var uid = user.uid;
    // ...
    // Get the JWT (see line below)
  } else {
    // User is signed out
    // ...
  }
});

您可以从用户对象中获取 JWT(存储在客户端的浏览器中)。

const jwt = await getIdToken().token;

(注意,我在这里混合了 async/await 样式和 .then 范式,所以你需要选择一个)。

一旦您有了 JWT,您就可以使用它来调用后端服务,通常在 HTTP 请求的标头中发送它。

服务器端:

从 HTTP 请求标头中提取 JWT 到 idToken,然后使用 verifyIdToken(idToken) 验证令牌。此方法在特权环境(Admin SDK)中运行。在幕后,verifyIdToken 联系 Firebase 身份验证服务以对 JWT 进行身份验证。 Firebase 身份验证服务托管在 Google 的基础架构中,但您无法直接访问它——只能通过 verifyIdToken 调用。

如果您的后端服务在地球的另一端运行,则调用 verifyIdToken 时会有更高的延迟。可能有一些缓存,但这肯定至少适用于您的第一个请求。这就是为什么我在您的问题下的评论中写道,您可能需要考虑在 GCP 中托管您的后端服务。

您不应该将 JWT 存储在数据库中,因为 Firebase 身份验证客户端每小时会重新生成 JWT。

一旦通过后端验证,您就可以从 JWT 中提取 uid。

// idToken comes from the client app
admin
  .auth()
  .verifyIdToken(idToken)
  .then((decodedToken) => {
    const uid = decodedToken.uid;
    // ...
  })
  .catch((error) => {
    // Handle error
  });

https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_the_firebase_admin_sdk

【讨论】:

  • 为什么我需要自己验证 idtoken?成功的电子邮件/密码登录后由firebase处理?这就是我使用 firebase 的原因 - 不必自己进行整个验证
  • 感谢您的详细回答。尽管它与我的问题不是 100% 相关,但它非常有价值,我可能很快就会回来。
【解决方案2】:

您绝对可以使用 UID 作为数据库中每个用户数据的唯一键。这就是它的用途。

我认为您可能误解了评论。它试图解决的问题是通过 API 调用将 UID 发送到您自己的后端。任何知道如何调用 API 端点的人都可以伪造该调用,这意味着他们可以发送他们想要的任何 UID。对于这些情况,客户端应用程序应该在后面提供一个 ID 令牌,以便使用 Firebase Admin SDK 进行验证。这是为您的后端发送用户信息的唯一安全方式,这样它就不会被黑客入侵。

如果您不将 UID 发送到后端,则无需发送令牌并对其进行验证。如果您只是在本地或通过其他实施安全规则的 Firebase 产品使用 UID,则完全无需担心令牌。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多