Angular+NestJS实现Google登录时access_token验证失败求助
解决Google登录token验证
invalid_token问题 一、先确认前端获取的Token类型
angularx-social-login默认可能返回id_token而非access_token,或需明确配置请求access_token:
- 初始化
SocialLoginModule时,指定正确的scope和响应类型:
@NgModule({ imports: [ SocialLoginModule.init({ autoLogin: false, providers: [ { id: GoogleLoginProvider.PROVIDER_ID, provider: new GoogleLoginProvider( '你的Google客户端ID', { scope: 'email profile openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', responseType: 'token' // 明确要求返回access_token } ) } ] }) ] })
- 登录时确认传递的是
authToken(即access_token),而非idToken:
signInWithGoogle(): void { this.authService.signIn(GoogleLoginProvider.PROVIDER_ID).then((user) => { console.log(user.authToken); // 核对此处输出是否为access_token this.http.post('/api/auth/google', { token: user.authToken }).subscribe(); }); }
二、后端验证的正确实现
1. 使用googleapis包验证access_token
确保参数名是access_token,并验证返回的aud字段匹配你的客户端ID:
import { google } from 'googleapis'; async validateGoogleToken(token: string) { const oauth2 = google.oauth2({ version: 'v2' }); try { const res = await oauth2.tokeninfo({ access_token: token }); if (res.data.aud !== '你的Google客户端ID') { throw new Error('Token audience不匹配'); } return res.data; } catch (err) { throw new Error('无效的access_token'); } }
2. 使用axios调用tokeninfo接口
参数需正确传递access_token,同时验证aud字段:
import axios from 'axios'; async validateGoogleToken(token: string) { try { const res = await axios.get('https://www.googleapis.com/oauth2/v3/tokeninfo', { params: { access_token: token } }); if (res.data.aud !== '你的Google客户端ID') { throw new Error('Token audience不匹配'); } return res.data; } catch (err) { throw new Error('无效的access_token'); } }
三、常见问题排查
- Token类型混淆:若前端误传
id_token给后端,用access_token参数验证会直接报错。此时要么前端改传authToken,要么后端改用id_token参数调用接口,或用google-auth-library的verifyIdToken方法验证id_token:
import { OAuth2Client } from 'google-auth-library'; const client = new OAuth2Client('你的Google客户端ID'); async validateGoogleIdToken(token: string) { const ticket = await client.verifyIdToken({ idToken: token, audience: '你的Google客户端ID' }); return ticket.getPayload(); }
- 客户端ID不匹配:确保前后端使用的是同一个Google Web客户端ID(区分Android/iOS客户端ID)。
- Token过期:access_token有效期仅1小时,可通过tokeninfo接口返回的
exp字段判断是否过期。 - Token被篡改:后端打印接收到的token,和前端控制台输出的对比,确认传输过程中未被修改。
内容的提问来源于stack exchange,提问作者Ghasem Khalili
相关产品推荐
相关产品推荐

