【问题标题】:AWS web and mobile hub applicationAWS Web 和移动中心应用程序
【发布时间】:2023-04-07 17:32:01
【问题描述】:

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

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

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

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

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

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

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

所以关键问题是:

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

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

我花费了大量的时间和精力,尝试了很多方法。

【问题讨论】:

    标签: ios amazon-web-services authentication mobile aws-mobilehub


    【解决方案1】:

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

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

    所以:

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

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

    因此,您只需更改 ID 即可正确连接所有内容。

    一般情况下,您需要修复Inf​​o.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 更改为您要使用的身份池 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 开放 ID 提供者(并将 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,使用两个不同的客户端并指定两个不同的提供者是首选。

    【讨论】:

    • 感谢您的好评。我已经为网络应用程序设置了用户池,所以我打算切换到使用它,但我不能,因为移动生成的用户池需要一个客户端密码,web/javascript 文档建议不要使用它,因为它是可见的给客户。 iOS 应用程序可以在没有秘密的情况下工作吗?该方法具有所需的秘密。
    • 在 API Gateway 上,我使用它为 Web 和移动设备提供一致的后端。我的计划是在大多数应用程序中使用它,并且只使用对 S3 的直接访问来上传和下载需要 IAM 策略的图像。我在这里担心的是,理想情况下,Web 应用程序将被允许访问某些用户的特定上传。有可能还是我应该使用不同的方法?
    • 这里有两个问题,1)如何在IOS api中指定缺少secret,2)安全问题。在没有秘密的情况下配置应用程序很容易,问题是如何为没有秘密的情况配置池。你是如何在 javascript 中做到这一点的(你用你的“Authenticate” api 调用传递了什么秘密?)。我们应该能够对 IOS 做同样的事情。关于问题 2,这需要一些调查,但我很感兴趣并且会试一试。如果这有帮助,请接受答案。
    • 此外,您应该能够(在用户池中)设置两个单独的应用程序,一个是移动应用程序(您可以在其中检查“生成密钥”),另一个是您的 Javascript 应用程序。这将是最好的(因为我们不必回答“如果我在 IOS 中关闭密钥会丢失什么)这个问题。我尝试设置单独的应用程序,一个有密钥,一个没有,它确实有效在游泳池上
    • 这个我已经研究过了,你可以做任何一种方式,我已经更新了答案告诉两种方法来处理它。
    猜你喜欢
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2013-05-23
    • 2015-10-14
    • 1970-01-01
    相关资源
    最近更新 更多