

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 Facebook 设置为身份池 IdP
Facebook

Amazon Cognito 身份池与 Facebook 配合使用，以便针对应用程序用户提供联合身份验证。本部分介绍如何使用 Facebook 作为 IdP 来注册和设置应用程序。

## 设置 Facebook


在对 Facebook 用户进行身份验证并与 Facebook 互动之前，请先在 Facebook APIs 上注册

[Facebook 开发人员门户](https://developers.facebook.com/)可帮助您设置应用程序。在将 Facebook 集成到您的 Amazon Cognito 身份池之前，请执行以下过程：

**注意**  
Amazon Cognito 身份池联合身份验证与 [Facebook Limited Login](https://developers.facebook.com/docs/facebook-login/limited-login) 不兼容。有关如何在不超过 Limited Login 权限集的情况下设置 Facebook Login for iOS 的更多信息，请参阅 *Meta for Developers* 中的 [Facebook Login for iOS - 快速入门](https://developers.facebook.com/docs/facebook-login/ios)。

**设置 Facebook**

1. 在 [Facebook 开发人员门户](https://developers.facebook.com/)中，使用 Facebook 凭证登录。

1. 从 **Apps**（应用程序）菜单中，选择 **Add a New App**（添加新应用程序）。

1. 选择一个平台，然后完成快速启动流程。

### Android


有关如何将 Android 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/android/getting-started)。

### iOS - Objective-C


有关如何将 OS Objective-C 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/ios/getting-started/)。

### iOS - Swift


有关如何将 iOS Swift 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/ios/getting-started/)。

### JavaScript


有关如何将 JavaScript 网络应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.3)。

## 在 Amazon Cognito 身份池控制台中配置身份提供者


使用以下过程配置身份提供者。

**添加 Facebook 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.amazonaws.cn/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Facebook**。

1. 输入你在 [Meta 开发者版中创建的 OAuth ](https://developers.facebook.com/)项目的**应用程序 ID**。有关更多信息，请参阅《Meta for Developers 文档》**中的 [Facebook 登录](https://developers.facebook.com/docs/facebook-login/)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

1. 选择**保存更改**。

## 使用 Facebook


### Android


要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/android)将 Facebook 开发工具包集成到应用程序中。然后，将 [**Login with Facebook**（使用 Facebook 登录）按钮](https://developers.facebook.com/docs/facebook-login/android)添加到 Android 用户界面。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 Amazon 资源的权限。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序中。

Facebook SDK 4.0 或更高版本：

```
Map<String, String> logins = new HashMap<String, String>();
logins.put("graph.facebook.com", AccessToken.getCurrentAccessToken().getToken());
credentialsProvider.setLogins(logins);
```

Facebook SDK 4.0 之前的版本：

```
Map<String, String> logins = new HashMap<String, String>();
logins.put("graph.facebook.com", Session.getActiveSession().getAccessToken());
credentialsProvider.setLogins(logins);
```

Facebook 登录流程在其开发工具包中初始化一个单例会话。Facebook 会话对象包含一个 OAuth 令牌，Amazon Cognito 使用该令牌为经过身份验证的最终用户生成 Amazon 证书。Amazon Cognito 还使用该令牌检查用户数据库，以确定是否存在与此特定 Facebook 身份匹配的用户。如果用户已存在，则 API 会返回现有的标识符。否则，API 将返回新的标识符。客户端开发工具包会自动在本地设备上缓存标识符。

**注意**  
设置登录映射后，调用`refresh`或`get`检索 Amazon 证书。

### iOS - Objective-C


要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/ios)将 Facebook 开发工具包集成到应用程序中。然后，向用户界面添加[“用 Facebook 登录”按钮](https://developers.facebook.com/docs/facebook-login/ios)。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，并将其绑定到唯一的 Amazon Cognito 身份池（联合身份）。

要向 Amazon Cognito 提供 Facebook 访问令牌，请实施 [https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios) 协议。

在实施 `logins` 方法时，返回一个包含 `AWSIdentityProviderFacebook` 的词典。此词典充当键，而经过身份验证的 Facebook 用户的当前访问令牌充当值，如以下代码示例所示。

```
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
    FBSDKAccessToken* fbToken = [FBSDKAccessToken currentAccessToken];
    if(fbToken){
        NSString *token = fbToken.tokenString;
        return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : token }];
    }else{
            return [AWSTask taskWithError:[NSError errorWithDomain:@"Facebook Login"
                                                          code:-1
                                                      userInfo:@{@"error":@"No current Facebook access token"}]];
    }
}
```

当您实例化 `AWSCognitoCredentialsProvider` 时，在构造函数中传递实施 `AWSIdentityProviderManager` 作为 `identityProviderManager` 的值的类。有关更多信息，请转到[AWSCognitoCredentialsProvider](https://github.com/aws-amplify/aws-sdk-ios)参考页面并选择**initWithRegion类型:identityPoolId: identityProviderManager**。

### iOS - Swift


要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/ios)将 Facebook 开发工具包集成到应用程序中。然后，向用户界面添加[“用 Facebook 登录”按钮](https://developers.facebook.com/docs/facebook-login/ios)。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，并将其绑定到唯一的 Amazon Cognito 身份池（联合身份）。

**注意**  
Amazon Cognito 身份池联合身份验证与 [Facebook Limited Login](https://developers.facebook.com/docs/facebook-login/limited-login) 不兼容。有关如何在不超过 Limited Login 权限集的情况下设置 Facebook Login for iOS 的更多信息，请参阅 *Meta for Developers* 中的 [Facebook Login for iOS - 快速入门](https://developers.facebook.com/docs/facebook-login/ios)。

要向 Amazon Cognito 提供 Facebook 访问令牌，请实施 [https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios) 协议。

在实施 `logins` 方法时，返回一个包含 `AWSIdentityProviderFacebook` 的词典。此词典充当键，而经过身份验证的 Facebook 用户的当前访问令牌充当值，如以下代码示例所示。

```
class FacebookProvider: NSObject, AWSIdentityProviderManager {
    func logins() -> AWSTask<NSDictionary> {
        if let token = AccessToken.current?.authenticationToken {
            return AWSTask(result: [AWSIdentityProviderFacebook:token])
        }
        return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
    }
}
```

当您实例化 `AWSCognitoCredentialsProvider` 时，在构造函数中传递实施 `AWSIdentityProviderManager` 作为 `identityProviderManager` 的值的类。有关更多信息，请转到[https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios)参考页面并选择**initWithRegion类型:identityPoolId: identityProviderManager**。

### JavaScript


要添加 Facebook 身份验证，请按照[适用于 Web 的 Facebook 登录](https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.3)中的说明操作，并在您的网站上添加 **Login with Facebook** （使用 Facebook 登录）按钮。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 Amazon 资源的权限。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序中。

```
FB.login(function (response) {

  // Check if the user logged in successfully.
  if (response.authResponse) {

    console.log('You are now logged in.');

    // Add the Facebook access token to the Amazon Cognito credentials login map.
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
      IdentityPoolId: 'IDENTITY_POOL_ID',
      Logins: {
        'graph.facebook.com': response.authResponse.accessToken
      }
    });

    // Obtain AWS credentials
    AWS.config.credentials.get(function(){
        // Access AWS resources here.
    });

  } else {
    console.log('There was a problem logging you in.');
  }

});
```

Facebook 软件开发工具包获取 OAuth 令牌，亚马逊 Cognito 使用该令牌为经过身份验证的最终用户 Amazon 生成证书。Amazon Cognito 还可以使用该令牌检查用户数据库，以确定是否存在与此特定 Facebook 身份匹配的用户。如果用户已存在，则 API 会返回现有的标识符。否则，将返回新的标识符。标识符由本地设备上的客户端开发工具包自动缓存。

**注意**  
设置登录映射后，请调用 `refresh` 或 `get` 以获取凭证。有关代码示例，请参阅[JavaScript 自述文件](https://github.com/amazon-archives/amazon-cognito-identity-js/blob/master/README.md)中的 “用例 17，将用户池与 Cognito 身份集成”。

### Unity


要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/unity)将 Facebook 开发工具包集成到应用程序中。Amazon Cognito 使用 `FB` 对象中的 Facebook 访问令牌生成与 Amazon Cognito 身份关联的唯一用户标识符。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序：

```
void Start()
{
    FB.Init(delegate() {
        if (FB.IsLoggedIn) { //User already logged in from a previous session
            AddFacebookTokenToCognito();
        } else {
            FB.Login ("email", FacebookLoginCallback);
        }
    });
}

void FacebookLoginCallback(FBResult result)
{
    if (FB.IsLoggedIn)
    {
        AddFacebookTokenToCognito();
    }
    else
    {
        Debug.Log("FB Login error");
    }
}

void AddFacebookTokenToCognito()
{
    credentials.AddLogin ("graph.facebook.com", AccessToken.CurrentAccessToken.TokenString);
}
```

使用 `FB.AccessToken` 之前，调用 `FB.Login()` 并确保 `FB.IsLoggedIn` 为 True。

### Xamarin


**Xamarin for Android：**

```
public void InitializeFacebook() {
    FacebookSdk.SdkInitialize(this.ApplicationContext);
    callbackManager = CallbackManagerFactory.Create();
    LoginManager.Instance.RegisterCallback(callbackManager, new FacebookCallback &lt; LoginResult &gt; () {
      HandleSuccess = loginResult = &gt; {
        var accessToken = loginResult.AccessToken;
        credentials.AddLogin("graph.facebook.com", accessToken.Token);
        //open new activity
      },
      HandleCancel = () = &gt; {
        //throw error message
      },
      HandleError = loginError = &gt; {
        //throw error message
      }
    });
    LoginManager.Instance.LogInWithReadPermissions(this, new List &lt; string &gt; {
      "public_profile"
    });
  }
```

**Xamarin for iOS：**

```
public void InitializeFacebook() {
  LoginManager login = new LoginManager();
  login.LogInWithReadPermissions(readPermissions.ToArray(), delegate(LoginManagerLoginResult result, NSError error) {
    if (error != null) {
      //throw error message
    } else if (result.IsCancelled) {
      //throw error message
    } else {
      var accessToken = loginResult.AccessToken;
      credentials.AddLogin("graph.facebook.com", accessToken.Token);
      //open new view controller
    }
  });
}
```