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

如何在AWS Cognito用户池注册时获取身份提供商OAuth令牌?

获取AWS Cognito注册时的Google OAuth令牌(离线访问)

Hey there! I’ve tackled this exact scenario before—getting Google’s access_token and refresh_token for offline access when users sign up via AWS Cognito. Let’s walk through why your initial attempts didn’t work, and the actionable fixes to make this happen.

为什么你的前两种方案没拿到令牌?

  • amazon-cognito-auth-js库:默认情况下,Cognito不会暴露第三方身份提供商的令牌,除非你显式配置属性映射并使用正确的OAuth流程。你之前看到的属性映射选项里没有令牌,是因为需要先创建自定义用户属性。
  • Google JS API + Cognito创建用户:这个思路是对的,但你大概率漏掉了请求offline_access权限(这是获取refresh令牌的关键),也没处理好联合登录后的令牌存储逻辑。

可行方案1:配置Cognito + amazon-cognito-auth-js获取令牌

这种方案完全依托Cognito生态,但需要仔细配置:

Step 1:准备Cognito用户池

  • 创建自定义属性:进入你的Cognito用户池 → Attributes → Add custom attribute,创建custom:google_access_token和custom:google_refresh_token(设置为可写)。
  • 配置Google身份提供商:在用户池的Identity providers → Google页面,确保:
    • 除了openid、email、profile,还添加了offline_access权限。
    • 在Attribute mapping里,将Google的access_token映射到你的custom:google_access_token属性,refresh_token映射到custom:google_refresh_token。
  • 更新应用客户端:确保你的应用客户端使用Authorization Code Grant流程(而非implicit流程),且包含offline_access权限。

Step 2:调整auth-js代码

使用授权码流程(获取refresh令牌必须),登录后获取映射的属性:

const authData = {
  ClientId: "YOUR_COGNITO_APP_CLIENT_ID",
  AppWebDomain: "YOUR_COGNITO_DOMAIN.auth.region.amazoncognito.com",
  TokenScopesArray: ["openid", "email", "profile", "offline_access"],
  RedirectUriSignIn: "YOUR_REDIRECT_URI",
  RedirectUriSignOut: "YOUR_LOGOUT_URI",
  ResponseType: "code" // 必须用code流程获取refresh令牌
};

const auth = new AmazonCognitoAuth(authData);
auth.userhandler = {
  onSuccess: (result) => {
    // 获取用户属性(包括映射的Google令牌)
    const userPool = new AmazonCognitoIdentity.CognitoUserPool({
      UserPoolId: "YOUR_COGNITO_USER_POOL_ID",
      ClientId: "YOUR_COGNITO_APP_CLIENT_ID"
    });
    const cognitoUser = userPool.getCurrentUser();
    
    cognitoUser.getUserAttributes((err, attributes) => {
      if (err) throw err;
      // 从自定义属性中提取Google令牌
      const googleAccessToken = attributes.find(attr => attr.Name === "custom:google_access_token")?.Value;
      const googleRefreshToken = attributes.find(attr => attr.Name === "custom:google_refresh_token")?.Value;
      
      // 用这些令牌实现Google API的离线访问
      console.log("Google Access Token:", googleAccessToken);
      console.log("Google Refresh Token:", googleRefreshToken);
    });
  },
  onFailure: (err) => console.error("登录失败:", err)
};

auth.getSession();

可行方案2:Google JS API + Cognito联合登录(更灵活)

这种方法让你在将用户传递给Cognito之前直接控制Google的令牌,适合需要将令牌存储在自有数据库的场景。

Step 1:Google API配置

初始化Google Auth SDK时,务必启用offline_access权限:

gapi.load("auth2", () => {
  auth2 = gapi.auth2.init({
    client_id: "YOUR_GOOGLE_CLIENT_ID",
    scope: "openid email profile offline_access" // 获取refresh令牌的关键
  });
});

Step 2:处理Google登录 + Cognito注册

用户通过Google认证后,获取令牌并联合登录到Cognito:

async function signInWithGoogle() {
  try {
    const googleUser = await auth2.signIn({ prompt: "consent" }); // 强制授权,确保重复登录也能获取refresh令牌
    const authResponse = googleUser.getAuthResponse();
    
    // 直接获取Google令牌
    const googleIdToken = authResponse.id_token;
    const googleAccessToken = authResponse.access_token;
    const googleRefreshToken = authResponse.refresh_token; // 仅首次授权时返回
    
    // 联合登录到Cognito(新用户会自动创建)
    const userPool = new AmazonCognitoIdentity.CognitoUserPool({
      UserPoolId: "YOUR_COGNITO_USER_POOL_ID",
      ClientId: "YOUR_COGNITO_APP_CLIENT_ID"
    });
    
    userPool.federatedSignIn(
      "Google",
      googleIdToken,
      googleUser.getBasicProfile(),
      (err, result) => {
        if (err) throw err;
        
        // 可选:将令牌保存到Cognito自定义属性
        const cognitoUser = result.user;
        const attributes = [
          new AmazonCognitoIdentity.CognitoUserAttribute({
            Name: "custom:google_access_token",
            Value: googleAccessToken
          }),
          new AmazonCognitoIdentity.CognitoUserAttribute({
            Name: "custom:google_refresh_token",
            Value: googleRefreshToken || ""
          })
        ];
        
        cognitoUser.updateAttributes(attributes, (updateErr) => {
          if (updateErr) console.error("更新属性失败:", updateErr);
          else console.log("Google令牌已保存到Cognito");
        });
      }
    );
  } catch (err) {
    console.error("Google + Cognito登录失败:", err);
  }
}

关键注意事项

  • Google Refresh令牌:Google仅在首次授权时返回refresh令牌。后续要获取新的refresh令牌,需要在Google登录调用中添加prompt: "consent"(如上例所示)。
  • Cognito属性限制:自定义属性有大小限制,确保你的令牌在限制范围内(Google令牌通常符合要求)。
  • 安全性:务必安全存储refresh令牌——不要长期在客户端暴露。使用Cognito的安全存储或自有加密数据库。

内容的提问来源于stack exchange,提问作者Bill Johnston

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:14:13