0

在 AWS 上,我希望创建一个允许用户通过移动设备、Web 或两者登录的应用程序。

我为后端使用 API Gateway、Lambdas 和 DynamoDB 创建了一个系统。我已经使用 JavaScript 登录到 web 工作,但在为 iOS 寻找相同代码的 Swift 示例时遇到问题(仅目标 C 可用)。所以我创建了一个移动集线器应用程序,导入了我现有的 API 并让 iOS 登录正常工作。

问题是 iOS 端使用 Mobile Hub,所以我现在有 2 个不同的用户池,因此您无法在 Web 上注册并在移动设备上登录(反之亦然)。

我尝试更改 iOS 应用程序中的设置以指向我的网络应用程序 Cognito 用户池设置并删除密钥,但由于它不能为空或为空而出错。

为什么移动集线器需要客户端密码?建议的 JavaScript 文档是不好的做法,因为可以反编译代码并提取秘密。

似乎没有任何一致的文档可以解释,我猜是移动和网络应用程序最常见的用例!

另一个问题是我可以为我的 API 网关下载我的 API 客户端 SDK,以便与 Web 应用程序和 iOS 应用程序一起使用。但是,生成的移动集线器应用程序是否包含基于 REST 的调用?我在这里发疯了还是官方的网络方法没有链接到官方的移动方法?

所以关键问题是:

  • 我可以或应该将移动应用程序更改为指向原始 Cognito 吗?
    • 如果是这样,我应该删除客户端密码吗?
    • 我可以在设置后有效地忽略 Mobile Hub 并将其纯粹用于代码生成吗?假设它正在工作,我可以将生成的客户端 SDK 用于我的 API 网关吗?

有没有更好的方法来设置 iOS(后来也是 Android)和网络应用程序?

我花了相当多的时间和精力,并尝试了很多方法。

4

1 回答 1

0

“Mobile Hub”很好地设置了用户池、身份池、IAM 角色等。

密钥等主要在 Info.plist 文件中提供,尽管(不明智地)用户池 AWSSignInProvider 的开发人员使其在配置文件中具有硬编码的密钥。

所以:

如果您不打算使用“Mobile Hub”控制台应用程序来更改您的移动应用程序配置,那么您将不再需要任何下载。在这种情况下,您不必担心 Info.plist 或配置文件的更改,您可以编辑您想要的内容。

目前尚不清楚您是要使用移动集线器创建的身份池并且只想插入您的用户池,还是要更改两个池。显然,如果您使用相同的身份池,则不需要下面的一些更改(它们很明显,因为您将它们更改为完全相同)。

因此,您所要做的就是更改 ID 以正确连接所有内容。

一般来说,您需要修复 Info.plist 和配置文件中所有下载的密钥和 ID,然后您需要更新服务器配置。更详细地说,这里是您需要更改它的地方:

在应用程序中:

将 Info.plist 中的所有键更新为您想要的键。(特别是 google 的凭据提供程序和身份管理器密钥)但如果您使用其他移动集线器服务,请检查那里的密钥。

如果您使用的是 s3,以及其他一些服务,目录名称/数据库名称也存储在代码中......我将其作为查找它们的活动。

在文件 MySampleApp->AmazonAWS->AWSConfiguration.swift 中编辑 Mobile hub 提供的键以匹配您的用户池(这样做时要低声咒骂,因为它们不在 Info.plist 中)

在控制台中:如果您的应用名称不存在,则将您的应用名称放入您的用户池 APP 列表中,并记录用户池 id、应用 id 和应用密码。

单击由移动集线器创建的联合身份和身份池,并更新身份验证提供程序以使用您的 cognito 用户池 ID 和应用程序 ID。

如果您还要更改身份池,那么您将需要查看您的 auth 和 unauth 用户的 IAM 角色,并专门编辑名为:.....yourapp....signin_MOBILEHUB_xxxxxxx 的策略,并更改身份该策略中的池 id 是您要使用的。对 auth 和 unauth 执行此操作。

(如果您只使用一个池,则可以更改 id,或者如果您将有多个身份池(用于测试......等),则将另一个添加到这样的 id 列表中)

            "Resource": [
            "arn:aws:cognito-identity:*:*:identityPool/us-east-1:8s8df8f8-sd9fosd9f0sdf-999sd99fd",
            "arn:aws:cognito-identity:*:*:identityPool/us-east-1:dfsf9099-sd9fosd9f0sdf-sd9f0sdf09f9s"
        ]

同样,在与角色关联的信任关系中,您需要修复 id,(如果您希望角色服务于多个身份池,则需要处理多个 ID)。这是在那里指定多个ID的方法。

      "Condition": {
    "ForAllValues:StringLike": {
      "cognito-identity.amazonaws.com:aud": [
        "us-east-1:8s8df8f8-sd9fosd9f0sdf-999sd99fsdfdd",
        "us-east-1:dfsf9099-sd9fosd9f0sdf-sd9f0sdf09f9s"
      ]
    },

如果您也使用谷歌...您需要确保在 IAM 配置中为谷歌提供 identityProvider(移动集线器为您完成),如果您使用自己的身份池,请在联合身份池授权提供者中配置您将需要选择 google open id provider(并将 google 也放入授权的提供者中(但我认为这部分不是必须的))

facebook 不使用 OpenID Connect,它具有配置到身份验证提供程序部分的专有方式,因此如果需要,请在身份池身份验证提供程序部分输入这些密钥。

这应该足以让它发挥作用。

不,你不会发疯……文档与当前的 IOS SDK 不匹配。移动集线器使用构建在 sdk TOP 上的 aws-mobilehub-helper-ios (github),因此文档也不适用于它!Mobile Hub Helper 的设计不错,因此我建议您使用它,而不是原始 SDK。

(最后......我在这里超出了我的深度,因为我不使用 API 网关,但我的理解是 API 网关是获取使用 AWS 服务的凭证的一种方式,并且使用移动集线器应用程序,您将正在使用 Cognito 获取这些凭据,因此我不确定您是否需要将 API 网关带入其中……完全)

更新

您可能不想为您的 javascript 应用程序的用户使用任何客户端密码,并在同一个池上使用 IOS 移动应用程序。这可以通过两种方式完成:

1)更好的方法是在用户池中创建两个不同的客户端。对于一个,您将生成一个客户端密码,对于另一个您将取消选中“生成客户端密码”框。

然后在您的联合身份池中,您转到身份验证提供者,然后单击 Cognito,并使用相同的用户池 ID 指定两个不同的提供者。(这实际上并不是两个不同的提供者,而是控制台让您指定它的方式)。然后您将两个不同的客户端 ID 放在这些提供程序中。

现在 IOS 应用程序和 Javascript 应用程序都可以访问池并从 identityProvider 和 credentialsProvider 获取身份验证和凭据。

2)一个不太好的方法。这种方式更糟糕的原因是因为我不知道它对您的移动应用程序安全性的影响(如果有的话)。在 AWS,没有人可以在不购买支持合同的情况下提出问题。但另一种方式是存在的。

您所做的是在两个应用程序中使用相同的客户端 ID,并且您不会生成客户端密码。为此,您在 clientSecret 中输入“nil”。这适用于一些警告。

首先,AWS Mobile Hub 的 AWSCognitoUserPoolsSignInProvider 中有一个错误。该类要求 clientSecret 不为空。但在 SDK 中,告诉 SDK 您不需要客户端密码的唯一方法是传递 nil!但是有一些解决方法。
(我所做的是使用 AWSCUPIdPSignInProvider.swift (我写的),它可以正常工作,而且我有一个版本可以使用 nil 作为秘密。我这样做是因为我测试它的速度更快。你可以如果您想使用它,请在 github 上找到该登录提供程序)

但更好的(更多面向未来的)解决方案可能是使用移动集线器提供的 AWSCognitoUserPoolsSignInProvider,但更改 AWSMobileClient 中的代码以配置和注册您自己的池,而不是让 AWSCognitoUserPoolsSignInProvider 为您完成。

我没有费心去尝试这个,(因为我们只需要这样做,因为 AWS 还没有开始更新 github aws-mobilehub-helper-ios)。但基本上在 AWSMobileClient 而不是这段代码:

    func setupUserPool() {
    // register your user pool configuration
    AWSCognitoUserPoolsSignInProvider.setupUserPoolWithId(AWSCognitoUserPoolId, cognitoIdentityUserPoolAppClientId: AWSCognitoUserPoolAppClientId, cognitoIdentityUserPoolAppClientSecret: AWSCognitoUserPoolClientSecret, region: AWSCognitoUserPoolRegion)

    AWSSignInProviderFactory.sharedInstance().registerAWSSignInProvider(AWSCognitoUserPoolsSignInProvider.sharedInstance(), forKey:AWSCognitoUserPoolsSignInProviderKey)

}

你会有这样的代码

        func setupUserPool() {
        // register your user pool configuration
    // find the service configuration (we don't know if they set it as default)
             let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1 (or your region), identityPoolId: "YourIdentityPoolId")
             let configuration = AWSServiceConfiguration(region: .USWest2 (or your region), credentialsProvider: credentialProvider)

    // configure and put your own user pool in the service configuration
                let userPoolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: AWSCognitoUserPoolAppClientId, clientSecret: nil, poolId:AWSCognitoUserPoolId)

    // now we register that pool with the service configuration using the key they use
                AWSCognitoIdentityUserPool.register(with: configuration, userPoolConfiguration: userPoolConfiguration, forKey: AWSCognitoUserPoolsSignInProviderKey)

AWSSignInProviderFactory.sharedInstance().registerAWSSignInProvider(AWSCognitoUserPoolsSignInProvider.sharedInstance(), forKey:AWSCognitoUserPoolsSignInProviderKey)

    }

但正如我上面所说,解决方案 1,使用两个不同的客户端并指定两个不同的提供者是首选。

于 2016-12-07T05:11:45.890 回答