繁体   English   中英

Firebase currentUser.getIdToken() 在 signInWithCustomToken 之后返回自定义令牌

[英]Firebase currentUser.getIdToken() returns custom token after signInWithCustomToken

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

更新

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

初始登录

Web 客户端代码

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 Admin 客户端的后端代码

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);
...

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

{ 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() ,它似乎是我的自定义令牌 - 或者至少有我的自定义声明和一些原始 id 令牌字段丢失。

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

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

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

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

  5. 根据上述更新,能够为 createCustomToken 的第一个参数发送任意值的目的是什么? 例如。 我通过了asdf并且令牌被很好地铸造并且随后被很好地解码。 这会影响 session 超时吗?

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

当您向 Firebase 身份验证用户帐户添加自定义声明时,它们不会立即对客户端“可见”,直到它们的 ID 令牌以某种方式刷新。 这种行为记录在案

在通过管理员 SDK 对用户修改新声明后,它们会通过 ID 令牌以下列方式传播到客户端的经过身份验证的用户:

  • 修改自定义声明后,用户登录或重新验证。 结果颁发的 ID 令牌将包含最新的声明。
  • 现有用户 session 在旧令牌过期后刷新其 ID 令牌。
  • 通过调用 currentUser.getIdToken(true) 强制刷新 ID 令牌。

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

最终,答案是不要仅仅使用自定义令牌来为您的 firebase 规则添加自定义声明。 它们是完全不同的概念。

除了那些 Fb 支持之外,自定义令牌还用于实现不受支持的身份验证提供程序 - 即 Google、Microsoft 等。自定义声明是您可以在安全规则中以及通过 user.getIdTokenResult() object 上的声明属性利用的键/值对在客户端。

我正在调试的超时问题是由于尝试重新使用自定义令牌,它不需要刷新,因为它不是目的。 getIdToken() 返回使用原始自定义令牌铸造时的任何声明编码的 Id 令牌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM