自定义Google Sign In按钮需点击两次才能触发的问题排查
我来帮你分析下这个问题——你遇到的两次点击才触发登录的情况,核心原因是第一次点击的时候Google Auth2库还没完成加载和初始化,导致点击事件还没真正绑定到按钮上。
问题根源拆解
你把startApp()绑定在了按钮的onclick事件里,第一次点击按钮时,才开始调用gapi.load('auth2')去加载Auth2库,这个加载是异步操作。等库加载完成、auth2初始化完毕后,才会执行attachSignin绑定点击处理器,但这时候第一次的点击已经结束了,所以得等第二次点击,按钮才会触发已经绑定好的登录流程。
而Google的标准按钮之所以正常,是因为它在页面加载阶段就完成了库的加载和事件绑定,不需要手动触发初始化步骤。
解决方案
这里提供两种靠谱的修复方式,你可以根据自己的需求选择:
方案一:提前加载并初始化Auth2库(推荐)
把初始化逻辑移到页面加载完成时执行,这样用户点击按钮时,Auth2已经准备就绪,一次点击就能触发登录:
<div id="button_google_login" class="customGPlusSignIn"> <span class="dont_close" style="padding-left: 12px;">Sign In with Google</span> </div> <script> var googleUser = {}; var auth2; // 页面加载完成后立即初始化Auth2 window.onload = function() { startApp(); }; var startApp = function() { gapi.load('auth2', function(){ auth2 = gapi.auth2.init({ client_id: '[Secret].apps.googleusercontent.com', cookiepolicy: 'single_host_origin' }); attachSignin(document.getElementById('button_google_login')); }); }; function attachSignin(element) { console.log(element.id); auth2.attachClickHandler(element, {}, function(googleUser) { var profile = googleUser.getBasicProfile(); console.log('ID: ' + profile.getId()); // 注意:别把这个ID传给后端,用ID token代替! console.log('Name: ' + profile.getName()); console.log('Image URL: ' + profile.getImageUrl()); console.log('Email: ' + profile.getEmail()); }, function(error) { // 处理错误或中断情况 }); } </script>
方案二:保留点击触发初始化,但优化流程
如果必须要在点击时才初始化,可以在第一次点击后禁用按钮,避免重复点击,同时初始化完成后直接触发登录流程,让用户只需要点一次:
<div id="button_google_login" class="customGPlusSignIn" onclick="startApp();"> <span class="dont_close" style="padding-left: 12px;">Sign In with Google</span> </div> <script> var googleUser = {}; var auth2; var startApp = function() { var button = document.getElementById('button_google_login'); // 禁用按钮,防止用户重复点击 button.disabled = true; gapi.load('auth2', function(){ auth2 = gapi.auth2.init({ client_id: '[Secret].apps.googleusercontent.com', cookiepolicy: 'single_host_origin' }); attachSignin(button); // 初始化完成后直接触发登录 auth2.signIn().then(function(googleUser) { var profile = googleUser.getBasicProfile(); console.log('ID: ' + profile.getId()); console.log('Name: ' + profile.getName()); console.log('Image URL: ' + profile.getImageUrl()); console.log('Email: ' + profile.getEmail()); }).catch(function(error) { // 出错后重新启用按钮 button.disabled = false; }); }); }; function attachSignin(element) { console.log(element.id); auth2.attachClickHandler(element, {}, function(googleUser) { var profile = googleUser.getBasicProfile(); console.log('ID: ' + profile.getId()); console.log('Name: ' + profile.getName()); console.log('Image URL: ' + profile.getImageUrl()); console.log('Email: ' + profile.getEmail()); }, function(error) { element.disabled = false; }); } </script>
额外提醒
Google官方明确不推荐把profile.getId()传给后端验证身份,正确的做法是使用googleUser.getAuthResponse().id_token,后端可以通过Google的验证接口来校验这个token的合法性。
内容的提问来源于stack exchange,提问作者user11235978
相关产品推荐
相关产品推荐

