使用@react-oauth/google的useGoogleLogin获取access_token后无法解码用户信息
问题原因与解决方案
核心错误原因
你用verifyIdToken去验证access_token本身就错了——这个方法是专门用来验证ID Token的,而useGoogleLogin默认返回的access_token不是JWT格式(JWT是三段式结构,用点分隔),自然会报Wrong number of segments in token错误。
解决步骤:拿到ID Token(获取用户信息+后端验证的正确方式)
要拿到能解码用户信息的ID Token,你需要给useGoogleLogin添加权限范围和响应类型配置:
import { useGoogleLogin } from '@react-oauth/google'; import jwtDecode from 'jwt-decode'; // 需先安装:npm install jwt-decode const login = useGoogleLogin({ onSuccess: async (response) => { // 现在response里会包含id_token console.log('id_token:', response.id_token); // 前端直接解码用户信息 const userInfo = jwtDecode(response.id_token); console.log('用户信息:', userInfo); // 包含name、email、picture等字段 // 把id_token发给后端验证 fetch('/api/verify-google-token', { method: 'POST', body: JSON.stringify({ idToken: response.id_token }), headers: { 'Content-Type': 'application/json' } }); }, // 必须添加openid scope,否则拿不到id_token scope: 'openid email profile', // 指定响应类型同时返回id_token和access_token responseType: 'id_token token' });
后端验证ID Token的正确代码
用google-auth-library的verifyIdToken验证ID Token(这时候就不会报错了):
const { OAuth2Client } = require('google-auth-library'); const client = new OAuth2Client('你的Google Client ID'); async function verifyIdToken(idToken) { const ticket = await client.verifyIdToken({ idToken: idToken, audience: '你的Google Client ID' // 要和前端用的clientId一致 }); const payload = ticket.getPayload(); console.log('验证后的用户信息:', payload); return payload; }
如果你非要用access_token验证(不推荐,因为无法直接拿到用户信息)
如果想通过access_token验证用户身份,后端不能用verifyIdToken,得调用Google的tokeninfo端点或者用getTokenInfo方法:
// 方法1:调用tokeninfo端点 async function verifyAccessToken(accessToken) { const response = await fetch(`https://oauth2.googleapis.com/tokeninfo?access_token=${accessToken}`); const data = await response.json(); // 验证client_id是否匹配你的应用 if (data.aud === '你的Google Client ID') { console.log('access_token验证通过'); return data; } } // 方法2:用google-auth-library的getTokenInfo async function verifyAccessToken(client, accessToken) { const tokenInfo = await client.getTokenInfo(accessToken); if (tokenInfo.aud === '你的Google Client ID') { console.log('access_token验证通过'); return tokenInfo; } }
内容的提问来源于stack exchange,提问作者Bikrant
相关产品推荐
相关产品推荐

