【问题标题】:firebase provider authentication refresh flowfirebase 提供者身份验证刷新流程
【发布时间】:2021-07-09 09:01:50
【问题描述】:

我正在尝试使用 firebase 身份验证来获取 google 访问令牌,以便调用 youtube API。

我最初能够像这样获得访问令牌:

const provider = firebase.auth.GoogleAuthProvider();
cosnt scopes = []; // ...scopes
scopes.forEach(scope => provider.addScope(scope));

firebase.auth().signInWithPopUp(provider)
  .then(userCredentials=> {
    const oauthCredentials = userCredentials.credentials;
    // using credentials for API calls
    axios.get("some-google-api-path", { params: { access_token: oauthCredentials.accessToken } }); // and so on...
  });

在访问令牌过期之前,这可以正常工作。 据我所知,firebase 似乎会自动刷新会话,但我可以找到一种方法来获取新的访问令牌。

我试过了:

firebase.auth().onAuthStateChange(user => {
  // could not find the access token on the user object
});

由于失败了,我尝试手动使用:

const token = firebase.auth.GoogleAuthProvider.credential(
  oauthCredentials.idToken,
  oauthCredentials.accessToken
);

const authResult = await firebase.auth().signInWithCredential(token);

问题是authResult 将只包含idTokenaccessToken,但不能同时包含两者,这取决于我赋予firebase.auth.GoogleAuthProvider.credential 函数的内容。

我错过了什么吗? 还有其他/更好的方法吗?

【问题讨论】:

    标签: javascript firebase firebase-authentication


    【解决方案1】:

    这里有两个令牌:

    • 刷新令牌,仅在用户主动登录后可用。由于它不会更改,因此您可以缓存此令牌 - Firebase SDK 实际上也这样做。
    • ID 令牌,可随时从当前用户处获得。此令牌会在一小时后过期,并由 Firebase SDK 自动刷新。

    因此,如果您想保留对刷新令牌的访问权限,则必须在用户首次主动登录时自行存储(通常在本地存储中)。

    【讨论】:

    • 我将令牌存储在localStorage,问题是一旦firebase刷新访问令牌,我似乎无法找到它,这会阻止我调用Google API,除非我强制用于重新登录。调用google API时需要持有access token,我想刷新流程需要id token
    • 据我所知,Firebase 只获得一次访问令牌(并在身份验证结果中向您公开),之后就再也没有。另请参阅 Jacob 在此处的出色解释:medium.com/@jwngr/… 并在其中“OAuth 访问令牌不用于向 Firebase 进行身份验证,对于那些访问令牌过期的提供商,Firebase 不会代表您刷新它们。”
    • 所以你建议我手动管理谷歌令牌刷新流程,如果它过期,或者firebase会话过期,终止两个会话?
    • 听起来它可以工作,但我希望 firebase 可以为我管理它,因为它已经为我进行了初始登录 :)
    • 另外,我在signInWithPopUp 结果中找不到谷歌刷新令牌:/
    【解决方案2】:

    显然,根据this,firebase 不会为您刷新其他提供商的令牌(不是事件 google)(谢谢Frank van Puffelen!)

    所以我改为手动向 google 进行身份验证(因为我使用 react,所以我使用了react-google-login),并从那里获取所有令牌。

    然后,一旦会话启动/刷新,我使用以下命令创建一个 firebase 会话:

    const token = firebase.auth.GoogleAuthProvider.credential(
      oauthCredentials.idToken,
      oauthCredentials.accessToken
    );
    
    const authResult = await firebase.auth().signInWithCredential(token);
    

    我希望这对任何人都有帮助,如果 firebase 改变这一点,我会接受另一个答案。

    【讨论】:

      猜你喜欢
      • 2018-10-31
      • 1970-01-01
      • 2021-05-25
      • 2023-03-15
      • 2020-08-21
      • 2014-04-07
      • 2017-12-25
      • 2020-01-23
      • 2016-12-19
      相关资源
      最近更新 更多