javascript - Firebase currentUser.getIdToken() 在signInWithCustomToken后返回自定义 token

标签 javascript firebase firebase-authentication firebase-admin

我正在使用 Firebase Auth 进行登录的 Next.js WEB/Node 应用上调试 session 超时问题。我正在利用自定义 token 来实现精细的 Firestore 安全规则。在调试时,我发现我发送到后端以创建自定义 token 的 idToken 在初始客户端调用后似乎是自定义 token 本身。至少它包含我的自定义声明,据我从文档中了解到,服务器只能按照 https://firebase.google.com/docs/auth/admin/verify-id-tokens 上的明显红色通知处理 idTokens。 。我不知道这是否是超时错误的根源,但这看起来很奇怪。

更新

在调查解码 token 上不存在 picture 字段的原因时,我发现 createCustomToken 的第一个参数错误地是用户集合文档的 firestore 文档 ID而不是 id token 的 uid 字段。所有相同的澄清问题仍然适用。不过,我希望这个失误能够解决问题。它使 picture 字段在 token 的后续解码中返回。但是, token 仍然有我的自定义声明,这可能仍然是问题,也可能不是问题。

首次登录

网络客户端代码

signInResult = await firebase.auth().signInWithPopup(googleProvider);
//... exception handling ...
const { user } = signInResult;
const fbToken = await user.getIdToken();
// axios POST request to backend with fbToken in data payload

使用 FB 管理客户端的后端代码

decodedToken = await adminClient.auth().verifyIdToken(data.fbIdToken);
//... validation and exception handling ...
// . If I log out decodedToken:
{ name: 'Blaine Garrett',
  picture: '...',
  iss: '...',
  aud: '...',
  auth_time: 1569160850,
  user_id: '...',
  sub: '...',
  iat: 1569160850,
  exp: 1569164450,
  email: '...',
  email_verified: true,
  firebase:
   { identities: { 'google.com': [Array], email: [Array] },
     sign_in_provider: 'google.com' },
  uid: '...' }
{ issued: 2019-09-22T14:00:50.000Z,
  expires: 2019-09-22T15:00:50.000Z }


let userId = decodedToken.uid; // As per update, this was not the case originally

// Build custom claims
customToken = await adminClient.auth().createCustomToken(userId, additionalClaims);
// return customToken in a 200 response

在客户端的服务器响应中

...
await firebase.auth().signInWithCustomToken(customToken);
...

后续调用 如果我在上述 signInWithCustomToken 之后调用 const firebaseIdToken = wait firebase.auth().currentUser.getIdToken(); 并将结果发送到后端并记录 token ,解码后的 token 是:

{ email: '...',
  user_roles: [ 'admin', 'support' ], // <-- my custom claims
  iss: '...',
  aud: '...',
  auth_time: 1569161153,
  user_id: '...',
  sub: '...',
  iat: 1569161163,
  exp: 1569164763,
  firebase: { identities: {}, sign_in_provider: 'custom' },
  uid: '...' }
{ issued: 2019-09-22T14:06:03.000Z,
  expires: 2019-09-22T15:06:03.000Z }
// Note: not everything is present on this token, including `picture` property and `email_verified`, etc

因此,即使我在客户端上调用 currentUser.getIdToken(),它似乎是我的自定义 token - 或者至少缺少我的自定义声明和一些原始 id token 字段。

  1. 这是预期的行为吗?即,如果之前调用过signInWithCustomToken,则getIdToken将返回自定义 token 。

  2. 如果给定 token 是自定义 token ,尝试在服务器上使用 verifyIdToken 是否有效?

  3. 这实际上是一个自定义 token 还是 FB 只是保留声明。 (缺少的个人资料字段让我感到困惑)。

  4. 有没有办法区分自定义 token 和 idToken?

  5. 上述每次更新能够为 createCustomToken 的第一个参数发送任意值的目的是什么?例如。我通过了 asdf 并且 token 被很好地类型转换并且随后被很好地解码。这会影响 session 超时吗?

感谢您的任何见解。再说一次,我不知道这是否是超时问题的根源,但我在尝试调试时遇到了这个问题,这让我质疑我对文档的理解。

最佳答案

当您向 Firebase 身份验证用户帐户添加自定义声明时,客户端不会立即“看到”它们,直到其 ID token 以某种方式刷新。此行为是documented :

After new claims are modified on a user via the Admin SDK, they are propagated to an authenticated user on the client side via the ID token in the following ways:

  • A user signs in or re-authenticates after the custom claims are modified. The ID token issued as a result will contain the latest claims.
  • An existing user session gets its ID token refreshed after an older token expires.
  • An ID token is force refreshed by calling currentUser.getIdToken(true).

因此,如果您需要客户端立即开始使用新声明,您应该使用第三个要点强制刷新。将 true 传递给 getIdToken。

关于javascript - Firebase currentUser.getIdToken() 在signInWithCustomToken后返回自定义 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58050178/

相关文章:

javascript - Javascript 动态编辑页面内容

android - 如何根据日期和时间对我的 RecyclerView 进行排序

firebase premession 奇怪的假

javascript - 使用 Selenium webdriver 加载动态 url

javascript - 远程 : true option is not working with file field in rails 4

python - Unity Firebase 插件失败(加载 Python DLL 时出错 : error code 14001)

javascript - 在 Firebase 中创建具有自定义详细信息的用户

ios - 甚至在我的操作在 main 方法中完成之前就触发了完成 block

javascript - 如何在段落淡入后立即淡出该段落?

javascript - 如何在没有异步 Promise 的情况下编写 Vuex 突变