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

如何用C#代码通过Facebook在Amazon Cognito用户池创建用户并实现API注册管控?

在C#中通过自有API实现Facebook联合登录到Amazon Cognito的用户创建流程

我明白你要的是后端API层面的实现——毕竟要在注册前加自定义业务规则,客户端直接对接Cognito肯定满足不了需求。下面我会一步步带你完成整个流程,从验证Facebook授权码到在Cognito中创建/关联用户,全程用C#落地。

整体逻辑梳理

先把整个流程串清楚,避免走弯路:

  1. 用户在前端选Facebook登录,完成OAuth2授权后拿到授权码(Authorization Code)
  2. 前端把授权码传给你的自有API
  3. 你的API依次做三件核心事:
    • 用授权码向Facebook换取用户基本信息和访问令牌
    • 执行你的自定义业务规则(比如检查用户是否符合注册条件、是否已有关联账户等)
    • 调用Cognito API创建用户(或关联已有用户),最终返回Cognito凭证给前端

第一步:准备依赖

先安装必要的NuGet包:

Install-Package AWSSDK.CognitoIdentityProvider
Install-Package System.Net.Http.Json

第二步:验证Facebook授权码并获取用户信息

前端传来授权码后,我们需要先向Facebook换取用户的核心信息(ID、邮箱、姓名)和Facebook的访问令牌。这里用原生HttpClient实现,比第三方SDK更灵活:

private async Task<FacebookUserInfo> ExchangeFacebookAuthCodeForUserInfo(string authCode, string redirectUri)
{
    var facebookClientId = "你的Facebook应用ID";
    var facebookClientSecret = "你的Facebook应用密钥";

    var tokenRequest = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["client_id"] = facebookClientId,
        ["client_secret"] = facebookClientSecret,
        ["code"] = authCode,
        ["redirect_uri"] = redirectUri  // 必须和前端发起授权时用的redirect_uri完全一致
    });

    using var httpClient = new HttpClient();
    var tokenResponse = await httpClient.PostAsync("https://graph.facebook.com/v18.0/oauth/access_token", tokenRequest);
    tokenResponse.EnsureSuccessStatusCode();

    var tokenData = await tokenResponse.Content.ReadFromJsonAsync<FacebookTokenResponse>();
    
    // 用获取到的access_token拉取用户基本信息
    var userInfoResponse = await httpClient.GetAsync($"https://graph.facebook.com/v18.0/me?fields=id,name,email&access_token={tokenData.AccessToken}");
    userInfoResponse.EnsureSuccessStatusCode();
    
    var userInfo = await userInfoResponse.Content.ReadFromJsonAsync<FacebookUserInfo>();
    userInfo.FacebookAccessToken = tokenData.AccessToken; // 存下来后续用
    return userInfo;
}

// 辅助序列化类
public class FacebookTokenResponse
{
    [JsonPropertyName("access_token")]
    public string AccessToken { get; set; }
}

public class FacebookUserInfo
{
    [JsonPropertyName("id")]
    public string Id { get; set; }
    [JsonPropertyName("name")]
    public string Name { get; set; }
    [JsonPropertyName("email")]
    public string Email { get; set; }
    public string FacebookAccessToken { get; set; }
}

第三步:应用自定义业务规则

这一步完全是你的自定义逻辑,比如检查用户邮箱是否已在业务系统存在、是否符合年龄要求、是否属于特定区域等。举个示例:

private void ValidateBusinessRules(FacebookUserInfo userInfo)
{
    // 示例1:强制要求用户授权邮箱(Facebook可能不返回邮箱,如果用户没同意)
    if (string.IsNullOrEmpty(userInfo.Email))
        throw new InvalidOperationException("请授权获取邮箱信息后再完成注册");
    
    // 示例2:检查邮箱是否已在业务数据库中存在(如果需要关联已有账号)
    // var existingBusinessUser = _businessDb.Users.FirstOrDefault(u => u.Email == userInfo.Email);
    // if (existingBusinessUser != null && !existingBusinessUser.HasLinkedFacebook)
    //     throw new InvalidOperationException("该邮箱已注册,请登录后关联Facebook账号");
    
    // 示例3:自定义年龄验证(需要额外拉取Facebook生日信息,这里省略)
    // ...
}

第四步:在Cognito中创建/关联用户

这是核心环节,我们用AWS SDK调用Cognito API,分两种情况处理:首次登录创建新用户 和 已有用户关联身份。

初始化Cognito客户端

建议从配置文件读取AWS凭证,不要硬编码:

private readonly AmazonCognitoIdentityProviderClient _cognitoClient;

public YourAuthService(IConfiguration config)
{
    var awsCredentials = new BasicAWSCredentials(
        config["AWS:AccessKey"], 
        config["AWS:SecretKey"]
    );
    _cognitoClient = new AmazonCognitoIdentityProviderClient(
        awsCredentials, 
        RegionEndpoint.GetBySystemName(config["AWS:CognitoRegion"])
    );
}

检查用户是否已存在于Cognito

通过Facebook用户ID查找是否已有关联的Cognito用户:

private async Task<UserType> FindCognitoUserByFacebookId(string facebookUserId)
{
    var request = new ListUsersRequest
    {
        UserPoolId = "你的Cognito用户池ID",
        Filter = $"custom:facebook_id = \"{facebookUserId}\""  // 需提前在Cognito中创建该自定义属性
    };

    var response = await _cognitoClient.ListUsersAsync(request);
    return response.Users.FirstOrDefault();
}

首次登录:创建用户并关联Facebook身份

如果用户不存在,先创建Cognito用户,再关联Facebook身份:

private async Task<AuthenticationResultType> CreateAndLinkCognitoUser(FacebookUserInfo facebookUser)
{
    // 1. 创建Cognito用户
    var createUserReq = new AdminCreateUserRequest
    {
        UserPoolId = "你的Cognito用户池ID",
        Username = facebookUser.Email,  // 用邮箱作为用户名,也可以用Facebook ID
        UserAttributes = new List<AttributeType>
        {
            new AttributeType { Name = "email", Value = facebookUser.Email },
            new AttributeType { Name = "name", Value = facebookUser.Name },
            new AttributeType { Name = "custom:facebook_id", Value = facebookUser.Id }
        },
        MessageAction = MessageActionType.SUPPRESS  // 禁用Cognito默认欢迎邮件,因为是社交登录
    };

    await _cognitoClient.AdminCreateUserAsync(createUserReq);

    // 2. 关联Facebook身份到Cognito用户
    var linkReq = new AdminLinkProviderForUserRequest
    {
        UserPoolId = "你的Cognito用户池ID",
        DestinationUser = new ProviderUserIdentifierType
        {
            ProviderName = "Cognito",
            ProviderAttributeName = "username",
            ProviderAttributeValue = facebookUser.Email
        },
        SourceUser = new ProviderUserIdentifierType
        {
            ProviderName = "Facebook",
            ProviderAttributeName = "Cognito_Subject",
            ProviderAttributeValue = facebookUser.Id
        }
    };

    await _cognitoClient.AdminLinkProviderForUserAsync(linkReq);

    // 3. 获取Cognito凭证
    return await GetCognitoAuthResult(facebookUser.FacebookAccessToken);
}

已有用户:直接获取凭证

如果用户已存在,直接用Facebook令牌发起认证:

private async Task<AuthenticationResultType> GetCognitoAuthResult(string facebookAccessToken)
{
    var authReq = new AdminInitiateAuthRequest
    {
        UserPoolId = "你的Cognito用户池ID",
        ClientId = "你的Cognito应用客户端ID",
        AuthFlow = AuthFlowType.ADMIN_OAUTH2_AUTH,
        AuthParameters = new Dictionary<string, string>
        {
            ["OAuth2Token"] = facebookAccessToken,
            ["ProviderName"] = "Facebook"
        }
    };

    var response = await _cognitoClient.AdminInitiateAuthAsync(authReq);
    return response.AuthenticationResult;
}

第五步:整合到API接口

最后把所有步骤整合到你的API控制器中:

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly YourAuthService _authService;

    public AuthController(YourAuthService authService)
    {
        _authService = authService;
    }

    [HttpPost("facebook")]
    public async Task<IActionResult> FacebookLogin([FromBody] FacebookLoginRequest request)
    {
        try
        {
            // 1. 换取Facebook用户信息
            var facebookUser = await _authService.ExchangeFacebookAuthCodeForUserInfo(
                request.AuthCode, 
                request.RedirectUri
            );
            
            // 2. 执行业务规则校验
            _authService.ValidateBusinessRules(facebookUser);
            
            // 3. 检查Cognito用户是否存在
            var existingCognitoUser = await _authService.FindCognitoUserByFacebookId(facebookUser.Id);
            
            var authResult = existingCognitoUser == null 
                ? await _authService.CreateAndLinkCognitoUser(facebookUser) 
                : await _authService.GetCognitoAuthResult(facebookUser.FacebookAccessToken);
            
            // 返回Cognito凭证给前端
            return Ok(new
            {
                authResult.IdToken,
                authResult.AccessToken,
                authResult.RefreshToken,
                authResult.ExpiresIn
            });
        }
        catch (Exception ex)
        {
            return BadRequest(new { Message = ex.Message });
        }
    }
}

public class FacebookLoginRequest
{
    public string AuthCode { get; set; }
    public string RedirectUri { get; set; }
}

关键注意事项

  • Facebook应用配置:确保Valid OAuth Redirect URIs包含前端的授权回调地址,且后端请求时的redirect_uri与前端完全一致。
  • Cognito配置:在用户池中启用Facebook作为身份提供商,配置好Facebook的应用ID和密钥,并提前创建custom:facebook_id自定义属性。
  • AWS权限:确保你的AWS凭证拥有cognito-idp:AdminCreateUser、cognito-idp:AdminLinkProviderForUser、cognito-idp:AdminInitiateAuth等权限。
  • 错误处理:生产环境中要细化错误处理,比如区分Facebook授权失败、业务规则不通过、Cognito调用异常等场景,返回更友好的提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:44:15