我一直致力于为我的应用程序集成 Google 登录,但遇到了一个有趣的问题。虽然登录过程是无缝的并且按预期工作,但我注意到刷新页面后,我似乎失去了与gapi的连接。我仍然保留 userDetails 和 accessToken。
我稍后在应用程序中使用gapi来获取日历事件,并且即使在页面刷新后此连接也保持完整至关重要。一切似乎都运转良好,直到我遇到这个问题。我的 Google 登录过程的主要功能似乎是问题的根源。
import { useState, useEffect } from "react";
import { gapi } from "gapi-script";
import axios from "axios";
import { useSelector } from "react-redux";
const google = window.google;
export const useGoogleSignIn = () => {
const [googleAccessToken, setGoogleAccessToken] = useState();
const [userDetails, setUserDetails] = useState();
const { hotCredintials } = useSelector((state) => state.hotCredintials);
const apiKey = "";
const clientID = "";
const refreshToken = ""
const clientSecret = ""
useEffect(() => {
// fetchData(apiRoutes.hotCredentials).then((res) => setCredentialKeys(res));
const accessTkn = localStorage.getItem("googleAccessToken");
setGoogleAccessToken((prev) => ({
...prev,
access_token: JSON.parse(accessTkn),
}));
}, []);
const onGoogleSignIn = () => {
const timestampInMilliseconds = new Date().getTime();
/* client google */
const client = google.accounts.oauth2.initTokenClient({
client_id: hotCredintials.find(({ credentialId }) => credentialId === "3")
?.credentialValue,
scope: SCOPES,
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse?.access_token) {
setGoogleAccessToken(tokenResponse);
localStorage.setItem(
"googleAccessToken",
JSON.stringify(tokenResponse.access_token)
);
localStorage.setItem(
"googleAccessTokenExpire",
JSON.stringify(timestampInMilliseconds)
);
gapi.client.setApiKey(apiKey);
}
},
});
client.requestAccessToken();
};
const onGoogleSignOut = () => {
google.accounts.id.disableAutoSelect();
// google.accounts.oauth2.revoke(googleAccessToken.access_token);
setGoogleAccessToken("");
setUserDetails("");
localStorage.removeItem("googleAccessToken");
};
useEffect(() => {
// refresh access token before it expires
const intervalId = setInterval(() => {
const expireTime = Number(
localStorage.getItem("googleAccessTokenExpire")
);
const timeLimit = expireTime + 3580 * 1000; // Convert 3580 seconds to milliseconds and add to expireTime
const timeNow = new Date().getTime();
if (googleAccessToken.access_token && timeNow > timeLimit) {
axios
.post(`https://oauth2.googleapis.com/token`, {
client_id: clientID,
client_secret: clientSecret,
grant_type: "refresh_token",
refresh_token:
refreshToken
})
.then((res) => {
setGoogleAccessToken((prev) => {
return {
...prev,
access_token: res.data.access_token,
expires_in: res.data.expires_in,
token_type: res.data.token_type,
scope: res.data.scope,
};
});
localStorage.setItem(
"googleAccessToken",
JSON.stringify(res.data.access_token)
);
localStorage.setItem(
"googleAccessTokenExpire",
JSON.stringify(newTimestampInMilliseconds)
);
})
.catch((err) => console.log(err));
}
}, 10000); // Refresh every 10 seconds
// Cleanup function to clear the interval
return () => clearInterval(intervalId);
}, [googleAccessToken]);
useEffect(() => {
if (googleAccessToken?.access_token)
fetch(
`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${googleAccessToken.access_token}`
)
.then((response) => response.json())
.then((content) => {
setUserDetails(content);
gapi.client.setApiKey(apiKey);
})
.catch((err) => {
console.log(err);
});
}, [googleAccessToken]);
return {
onGoogleSignIn,
onGoogleSignOut,
userDetails,
};
};
已授权gapi修复
useEffect(() => {
if (googleAccessToken?.access_token)
gapi.auth.authorize(
{
client_id: clientID,
scope: SCOPES,
immediate: true,
},
function (authResult) {
console.log({ authResult });
if (authResult && !authResult.error) {
// gapi.auth.setToken(googleAccessToken);
} else {
console.log("Failed to set token:", authResult.error);
}
}
);
}, [googleAccessToken]);