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

如何在.NET中通过Google OAuth2令牌完成AWS Cognito用户认证?

解决方案

你需要通过Cognito联合身份认证流程实现「存在则登录,不存在则创建」的逻辑,核心是先验证Google令牌合法性,再查询关联Cognito用户,最后生成Cognito会话令牌。以下是具体步骤和.NET代码实现:

1. 验证Google ID Token合法性

这一步是必要的,防止伪造令牌。使用Google官方库Google.Apis.Auth完成验证:

using Google.Apis.Auth;

var googleIdToken = "从前端接收的Google ID Token";
var googleClientId = "你的Google OAuth客户端ID";

var validationSettings = new GoogleJsonWebSignature.ValidationSettings
{
    Audience = new List<string> { googleClientId }
};

// 验证并解析令牌,失败会抛出异常
var googleUserPayload = await GoogleJsonWebSignature.ValidateAsync(googleIdToken, validationSettings);

2. 查询Cognito用户池是否存在关联用户

通过Google用户的sub(唯一标识)查询Cognito用户,避免邮箱重复的问题:

using Amazon.CognitoIdentityProvider;
using Amazon.CognitoIdentityProvider.Model;

var cognitoClient = new AmazonCognitoIdentityProviderClient(RegionEndpoint.YourRegion); // 替换为你的用户池区域
var userPoolId = "你的Cognito用户池ID";

var listUsersRequest = new ListUsersRequest
{
    UserPoolId = userPoolId,
    Filter = $"identities[0].userId = \"{googleUserPayload.Sub}\""
};

var listUsersResponse = await cognitoClient.ListUsersAsync(listUsersRequest);
var existingUser = listUsersResponse.Users.FirstOrDefault();

3. 不存在则创建Cognito用户并关联Google身份

如果用户未在Cognito中存在,先创建本地用户,再关联Google身份提供商:

if (existingUser == null)
{
    // 1. 创建Cognito本地用户
    var createUserRequest = new AdminCreateUserRequest
    {
        UserPoolId = userPoolId,
        Username = googleUserPayload.Email, // 用邮箱作为用户名,或用Google的sub
        UserAttributes = new List<AttributeType>
        {
            new AttributeType { Name = "email", Value = googleUserPayload.Email },
            new AttributeType { Name = "email_verified", Value = "true" } // Google已验证邮箱,直接设为true
        },
        TemporaryPassword = Guid.NewGuid().ToString() // 临时密码,关联第三方后无需使用
    };

    await cognitoClient.AdminCreateUserAsync(createUserRequest);

    // 2. 关联Google身份到Cognito用户
    var linkProviderRequest = new AdminLinkProviderForUserRequest
    {
        UserPoolId = userPoolId,
        DestinationUser = new ProviderUserIdentifierType
        {
            ProviderName = "Cognito",
            ProviderAttributeName = "username",
            ProviderAttributeValue = googleUserPayload.Email
        },
        SourceUser = new ProviderUserIdentifierType
        {
            ProviderName = "Google",
            ProviderAttributeName = "sub",
            ProviderAttributeValue = googleUserPayload.Sub
        }
    };

    await cognitoClient.AdminLinkProviderForUserAsync(linkProviderRequest);

    // 获取刚创建的用户信息
    existingUser = (await cognitoClient.AdminGetUserAsync(new AdminGetUserRequest
    {
        UserPoolId = userPoolId,
        Username = googleUserPayload.Email
    })).User;
}

4. 生成Cognito会话令牌(登录)

使用Google的ID Token向Cognito发起认证,获取Cognito的ID/Access/Refresh令牌,返回给前端使用:

var clientId = "你的Cognito应用客户端ID";
var authRequest = new AdminInitiateAuthRequest
{
    UserPoolId = userPoolId,
    ClientId = clientId,
    AuthFlow = AuthFlowType.AuthenticationProvider,
    AuthParameters = new Dictionary<string, string>
    {
        { "PROVIDER_NAME", "Google" },
        { "ID_TOKEN", googleIdToken }
    }
};

var authResponse = await cognitoClient.AdminInitiateAuthAsync(authRequest);

// 封装Cognito令牌返回给前端
var cognitoTokens = new
{
    IdToken = authResponse.AuthenticationResult.IdToken,
    AccessToken = authResponse.AuthenticationResult.AccessToken,
    RefreshToken = authResponse.AuthenticationResult.RefreshToken
};

关键注意事项

  • 确保你的Cognito用户池已在控制台配置Google作为身份提供商,并填写正确的Google OAuth客户端ID和密钥。
  • 前端后续请求需携带Cognito的IdToken或AccessToken,后端通过Cognito SDK验证令牌合法性即可。
  • 若使用email作为Cognito用户名,需确保用户池允许邮箱作为用户名,且开启邮箱唯一性验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:50:19