为何Sign in With Google示例代码返回错误Token无法登录Firebase?
解决方案:分离Google认证(Firebase登录)与Calendar授权流程
你遇到的核心问题是把**用户认证(获取ID Token用于Firebase登录)和API授权(获取Access Token调用Calendar)**两个流程混在了一起,新版Google Identity Services已经明确将这两个环节拆分,不能通过一次请求同时拿到两种令牌。
正确的实现步骤
- 先完成Firebase登录的认证流程:通过Sign In With Google组件获取ID Token,传入Firebase完成用户登录。
- 再单独发起Calendar API的授权请求:基于已登录的用户身份,获取访问Calendar所需的Access Token。
具体代码示例
1. 引入Google Identity Services脚本
在HTML中添加:
<script src="https://accounts.google.com/gsi/client" async defer></script>
2. 实现Firebase登录的认证逻辑
// 初始化Sign In With Google按钮 window.onload = () => { google.accounts.id.initialize({ client_id: '你的Google客户端ID', callback: handleAuthResponse }); google.accounts.id.renderButton( document.getElementById('g_id_signin'), { theme: 'outline', size: 'large' } ); }; // 处理认证回调,完成Firebase登录 function handleAuthResponse(response) { // 这里的response.credential就是Firebase需要的ID Token const idToken = response.credential; const firebaseCredential = firebase.auth.GoogleAuthProvider.credential(idToken); firebase.auth().signInWithCredential(firebaseCredential) .then(() => { console.log('Firebase登录成功'); // 登录后发起Calendar授权 requestCalendarAccess(); }) .catch(err => console.error('Firebase登录失败:', err)); }
3. 发起Calendar API的授权请求
function requestCalendarAccess() { const tokenClient = google.accounts.oauth2.initTokenClient({ client_id: '你的Google客户端ID', scope: 'https://www.googleapis.com/auth/calendar.readonly', // 根据需求调整权限 callback: (tokenRes) => { if (tokenRes.error) throw tokenRes; // 拿到Access Token,用于调用Calendar API const accessToken = tokenRes.access_token; // 示例:拉取用户主日历事件 fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(res => res.json()) .then(data => console.log('日历事件:', data)) .catch(err => console.error('Calendar API调用失败:', err)); } }); // 请求授权令牌,prompt: 'consent'会强制弹出权限确认框,也可用'none'检查已有权限 tokenClient.requestAccessToken({ prompt: 'consent' }); }
关键注意事项
- 确保你的Google Cloud控制台中,客户端ID已配置正确的OAuth回调地址(包括Firebase的回调和你的应用域名)。
- 权限范围要匹配你的需求:只读用
calendar.readonly,读写用calendar,不要请求超出必要的权限。 - 统一使用新版Google Identity Services(
google.accounts命名空间),不要混用旧的gapi.auth2API,避免流程冲突。
内容的提问来源于stack exchange,提问作者Joshua Dance
相关产品推荐
相关产品推荐

