You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Firebase用户重新认证问题咨询:Google登录后access_token刷新失败

How to Properly Refresh Google OAuth Access Tokens for Gmail API in Firebase Auth

Hey there, I’ve been in your exact situation before—trying to refresh a Google access token for Gmail API using Firebase’s endpoint and getting stuck with 403 errors. The core issue here is a common mix-up: Firebase’s securetoken.googleapis.com endpoint is for refreshing Firebase ID Tokens, not Google OAuth 2.0 access tokens. The token you’re getting back from that request is a new Firebase ID Token, which Gmail API doesn’t recognize—hence the 403.

Let’s break down the correct ways to fix this:

Firebase Auth automatically manages refreshing Google OAuth access tokens as long as the user is logged in and the refresh token is valid. You can fetch the latest access token directly from the authenticated user object:

Code Example

// Get the currently logged-in user
const currentUser = firebase.auth().currentUser;

if (currentUser) {
  // Force a token refresh to get the latest OAuth access token
  currentUser.getIdTokenResult(true)
    .then(idTokenResult => {
      // Extract the Google access token from the token claims
      const googleAccessToken = idTokenResult.claims.firebase.sign_in_attributes.oauth_access_token;
      
      // Update GAPI with the fresh token
      gapi.client.setToken({ access_token: googleAccessToken });
      
      // Now your Gmail API calls should work again!
    })
    .catch(error => {
      console.error("Failed to refresh access token:", error);
      // If this fails, you might need to re-authenticate the user (e.g., refresh token expired)
    });
}

Alternatively, you can reload the user and fetch their credentials directly:

currentUser.reload()
  .then(() => currentUser.getRedirectResult())
  .then(result => {
    const credential = firebase.auth.GoogleAuthProvider.credentialFromResult(result);
    const newAccessToken = credential.accessToken;
    gapi.client.setToken({ access_token: newAccessToken });
  })
  .catch(error => console.error("Error refreshing credentials:", error));

Option 2: Manually Call Google’s OAuth Token Refresh Endpoint

If you prefer to handle the refresh manually, use Google’s official OAuth 2.0 token endpoint instead of Firebase’s. You’ll need your Google Client ID and Client Secret (found in the Google Cloud Console under your project’s OAuth 2.0 credentials).

Code Example (using fetch)

fetch("https://oauth2.googleapis.com/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  body: new URLSearchParams({
    grant_type: "refresh_token",
    refresh_token: "<YOUR_SAVED_GOOGLE_REFRESH_TOKEN>",
    client_id: "<YOUR_GOOGLE_CLIENT_ID>",
    client_secret: "<YOUR_GOOGLE_CLIENT_SECRET>"
  })
})
.then(response => response.json())
.then(data => {
  if (data.access_token) {
    // Update GAPI with the new access token
    gapi.client.setToken({ access_token: data.access_token });
  } else {
    console.error("Token refresh failed:", data.error);
    // Handle cases where refresh token is invalid (e.g., re-prompt user to login)
  }
})
.catch(error => console.error("Network error during token refresh:", error));

Key Notes to Avoid Future Issues

  • Refresh Token Validity: Google refresh tokens can expire or be revoked (e.g., if the user changes their password or revokes your app’s permissions). If you get an error here, you’ll need to redirect the user to re-authenticate with Google.
  • Permissions: Ensure your Google Cloud Console project has the https://mail.google.com/ scope enabled in the OAuth consent screen, and that your app is approved for this scope (if it’s a production app).
  • Firebase vs Google Tokens: Always remember—Firebase ID Tokens are for authenticating with Firebase services, while Google OAuth tokens are for accessing Google APIs like Gmail. Don’t mix them up!

内容的提问来源于stack exchange,提问作者Piotr Sobuś

火山引擎 最新活动