You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:52:39