在NestJS中使用passport-google-oauth20:Access与Refresh Tokens作用及用法问询
Passport-Google-OAuth20中validate方法的令牌参数详解
在NestJS结合passport-google-oauth20开发时,validate方法接收accessToken和refreshToken是OAuth2.0协议的标准设计——哪怕基础登录功能不需要它们,框架也会按协议要求传入,目的是给你预留扩展业务逻辑的空间。
一、令牌的核心用途
Access Token(访问令牌)
- 是Google授权服务器颁发的短期凭证,用于代表用户向Google的各类API(比如Google Drive、Gmail API)发起请求,获取用户的额外资源或数据。
- 有效期通常较短(比如1小时),过期后无法再调用Google的API接口。
Refresh Token(刷新令牌)
- 是长期有效的凭证,专门用来在
accessToken过期时,向Google的授权服务器申请新的accessToken,无需用户再次登录授权。 - 只有在首次授权或用户重新授权时才会返回,只要用户不取消对应用的授权,它就能持续使用(部分场景下会失效,比如用户修改账号密码)。
二、具体用法与实现逻辑
1. 保存令牌到数据库
如果你的应用需要后续调用Google API,或者实现自动续期功能,可以在validate方法中把令牌和用户信息绑定保存:
async validate( accessToken: string, refreshToken: string, profile: any, ): Promise<any> { // 根据Google返回的用户唯一标识查询或创建本地用户 let user = await this.userService.findOneByGoogleId(profile.id); if (!user) { user = await this.userService.create({ googleId: profile.id, email: profile.emails[0].value, name: profile.displayName, }); } // 更新用户记录中的令牌 await this.userService.update(user.id, { accessToken, refreshToken }); // 返回用户对象供NestJS后续处理登录逻辑 return user; }
2. 调用Google API示例
使用保存的accessToken调用Google的用户信息API(需提前在Google Cloud Console开启对应API权限):
// 假设已从数据库取出用户的accessToken和refreshToken import axios from 'axios'; async fetchGoogleUserExtraData(accessToken: string, user: any) { try { const response = await axios.get('https://www.googleapis.com/oauth2/v3/userinfo', { headers: { Authorization: `Bearer ${accessToken}` }, }); return response.data; } catch (error) { // 处理令牌过期的情况 if (error.response?.status === 401) { // 用refreshToken获取新的accessToken const newTokens = await this.refreshGoogleAccessToken(user.refreshToken); // 更新数据库中的令牌并重试请求 await this.userService.update(user.id, newTokens); return this.fetchGoogleUserExtraData(newTokens.accessToken, user); } throw error; } } // 刷新accessToken的方法 async refreshGoogleAccessToken(refreshToken: string) { const response = await axios.post('https://oauth2.googleapis.com/token', { client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, refresh_token: refreshToken, grant_type: 'refresh_token', }); return { accessToken: response.data.access_token, refreshToken: response.data.refresh_token || refreshToken, // 部分场景会返回新的refreshToken }; }
3. 关键配置提示
要获取refreshToken,必须在GoogleStrategy的构造函数中设置accessType: 'offline',否则Google不会返回该令牌:
// GoogleStrategy构造函数配置 super({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: 'http://localhost:3000/auth/google/callback', scope: ['email', 'profile'], accessType: 'offline', // 必须设置才能拿到refreshToken });
如果你的业务不需要调用Google API,完全可以忽略这两个令牌,只处理profile信息完成基础登录——这也是你当前功能正常的原因。
内容的提问来源于stack exchange,提问作者meditativeUser
相关产品推荐
相关产品推荐

