sub*_*amX 7 javascript google-oauth google-signin google-identity react-google-login
我正在使用 Google 身份服务,并面临一些问题。看一下下面的函数loginUser并得到access_token:
const client = (window as any).google.accounts.oauth2.initTokenClient({
client_id: process.env.GOOGLE_CLIENT_ID,
scope: `profile email`,
callback: '' // defined at request time
});
const loginUser = async () => {
const tokenResponse = await new Promise<TokenResponse>((resolve, reject) => {
try {
// Settle this promise in the response callback for requestAccessToken()
client.callback = (resp) => {
if (resp.error !== undefined) {
reject(resp);
}
resolve(resp);
};
// requesting access token
client.requestAccessToken({ prompt: 'consent' });
} catch (err) {
console.log(err)
}
});
return tokenResponse;
}
Run Code Online (Sandbox Code Playgroud)
调用loginUser()会导致一个新的弹出窗口。
tokenResponse(其中包含access_token)。效果很好。pop-up,则Promise永远不会解析,因为我们正在等待回调触发,而这永远不会发生。有没有办法检测用户是否关闭了pop-up?
小智 7
我认为你可以在“error_callback”中做一些事情。您可以在以下位置找到详细信息:处理错误
const client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: myCallback,
error_callback: myErrorCallback // You can do something when popup window closed
});Run Code Online (Sandbox Code Playgroud)
看起来谷歌开发人员现在已经将错误处理程序添加到新的谷歌身份服务中。:) 查看文档https://developers.google.com/identity/oauth2/web/guides/error。
(我还没有测试过它。因此将其作为一个潜在的解决方案)。快乐编码!
如果您遇到此问题,可以考虑以下两种解决方案。
返回到旧的gapi登录状态。(不推荐,因为它很快就会被弃用)。有关弃用的更多详细信息,请参阅Google 的此博客。
focus我们在打开弹出窗口后添加一个 JavaScript事件监听器。因此,每当用户关闭弹出窗口并返回到 时parent window,我们都将其视为client_focused_back_to_window/pop_up_closed事件。
唯一的边缘情况是用户不关闭弹出窗口并直接返回到窗口;事件focus监听器将被触发。但我认为这没关系,因为如果用户再次单击Sign In with Google按钮,相同的弹出窗口将被重复使用(感谢_blankGoogle Identity 服务在创建弹出窗口时使用的参数)。
const client = (window as any).google.accounts.oauth2.initTokenClient({
client_id: process.env.GOOGLE_CLIENT_ID,
scope: `profile email`,
callback: '' // defined at request time
});
/**
* Function to login the user and return the tokenResponse
*
* It throws error if the login fails or the user cancels the login process
*/
const loginUser = async () => {
const tokenResponse = await new Promise<google.accounts.oauth2.TokenResponse>(
(resolve, reject) => {
const focusEventHandler = () => {
reject({
error: 'client_focused_back_to_window',
});
window.removeEventListener('focus', focusEventHandler); // removing the event listener to avoid memory leaks
};
// adding an event listener to detect if user is back to the webpage
// if the user "focus" back to window then we shall close the current auth session
window.addEventListener('focus', focusEventHandler);
// Settle this promise in the response callback for requestAccessToken()
client.callback = (resp) => {
if (resp.error) {
reject(resp);
}
resolve(resp);
};
// requesting access token
client.requestAccessToken({ prompt: 'consent' });
},
);
return tokenResponse;
}
Run Code Online (Sandbox Code Playgroud)
PS:我们一直在生产中使用这个解决方案,到目前为止,已有数千甚至数百万用户尝试通过 Google 登录。到目前为止一切都运行良好。
| 归档时间: |
|
| 查看次数: |
3220 次 |
| 最近记录: |