gpt4 book ai didi

ios - iOS (Swift) 应用程序中的 AWS Cognito 用户池

转载 作者:技术小花猫 更新时间:2023-10-29 10:20:18 24 4
gpt4 key购买 nike

我正在尝试在我的 iOS (Swift) 应用程序中实现新的 AWS Cognito 用户池,但我正在努力使登录过程正常工作。我基本上是在尝试遵循可用的示例 here .

这是我到目前为止:

应用委托(delegate):

class AppDelegate: UIResponder, UIApplicationDelegate, AWSCognitoIdentityInteractiveAuthenticationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: nil)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = serviceConfiguration
let configurationUserPool = AWSCognitoIdentityUserPoolConfiguration(
clientId: "###",
clientSecret: "#########",
poolId: "###")
AWSCognitoIdentityUserPool.registerCognitoIdentityUserPoolWithConfiguration(serviceConfiguration, userPoolConfiguration: configurationUserPool, forKey: "UserPool")
self.userPool = AWSCognitoIdentityUserPool(forKey: "UserPool")

self.userPool!.delegate = self

return true
}

func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let logInNavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("LogInNavigationController") as! UINavigationController

dispatch_async(dispatch_get_main_queue(), {
self.window?.rootViewController = logInNavigationController
})

let logInViewController = mainStoryboard.instantiateViewControllerWithIdentifier("LogInViewController") as! LogInViewController
return logInViewController
}
}

登录 View Controller :
class LogInViewController: UIViewController, AWSCognitoIdentityPasswordAuthentication {
var usernameText : String?
var passwordAuthenticationCompletion = AWSTaskCompletionSource()

func getPasswordAuthenticationDetails(authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletionSource: AWSTaskCompletionSource) {
self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource

dispatch_async(dispatch_get_main_queue(), {
if self.usernameText == nil {
self.usernameText = authenticationInput.lastKnownUsername
}
})
}

func didCompletePasswordAuthenticationStepWithError(error: NSError) {
dispatch_async(dispatch_get_main_queue(), {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let mainNavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("MainNavigationController") as! UINavigationController
(UIApplication.sharedApplication().delegate as! AppDelegate).window?.rootViewController = mainNavigationController
})
}

func logInButtonPressed() {
self.passwordAuthenticationCompletion.setResult(AWSCognitoIdentityPasswordAuthenticationDetails(username: emailTextField.text, password: passwordTextField.text))
}
}

当我点击登录按钮时,似乎什么也没有发生,但如果我再次点击它,我会得到一个 NSInternalInconsistencyException(我相信这是因为 AWSTask 结果已经设置)。

对此的任何帮助将不胜感激。我正在使用适用于 iOS 版本 2.4.1 的 AWS 开发工具包。

更新:

不是我最初问题的解决方案,但我已经能够通过使用显式登录方法而不是委托(delegate)方法让用户池工作(有关详细信息,请参阅此 page)。这是我的 SignInViewController 中的代码:
class SignInViewController: UIViewController {
@IBAction func signInButtonTouched(sender: UIButton) {
if (emailTextField.text != nil) && (passwordTextField.text != nil) {
let user = (UIApplication.sharedApplication().delegate as! AppDelegate).userPool!.getUser(emailTextField.text!)
user.getSession(emailTextField.text!, password: passwordTextField.text!, validationData: nil, scopes: nil).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {
(task:AWSTask!) -> AnyObject! in

if task.error == nil {
// user is logged in - show logged in UI
} else {
// error
}

return nil
})
} else {
// email or password not set
}
}
}

然后,为了使用 AWS 服务(在我的情况下,它位于与 Cognito 不同的区域),我使用用户池创建了一个新的凭据提供程序:
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: "###", identityProviderManager: (UIApplication.sharedApplication().delegate as! AppDelegate).userPool!)
let serviceConfiguration = AWSServiceConfiguration(region: .APNortheast1, credentialsProvider: credentialsProvider)
AWSLambdaInvoker.registerLambdaInvokerWithConfiguration(serviceConfiguration, forKey: "Lambda")
let lambdaInvoker = AWSLambdaInvoker(forKey: "Lambda")

另一个问题是,我每次启动应用程序时都会看到此错误:“在 info.plist 中找不到有效的‘AWSDefaultRegionType’、‘AWSCognitoRegionType’和‘AWSCognitoIdentityPoolId’值。”。这似乎与我用来跟踪崩溃的 Fabric 相关。我通过更改 AppDelegate 中的这一行解决了这个问题:
Fabric.with([AWSCognito.self, Crashlytics.self])

对此:
Fabric.with([Crashlytics.self])

我希望这对其他人有帮助。

最佳答案

更新 6 :(这次真的是最后一次)

值得一提的是,(最后)AWS 已经让 AWS Mobile Hub 构建了一个非常好的演示应用程序,其中包括用户池作为 SignInProvider(谷歌和 Facebook 也是如此)。该架构(在我看来)非常出色(他们将身份管理和从身份验证中获取凭据分开了)
一探究竟

更新 5:(和最终)

有一个相当完整的示例实现,以及一些关于它在另一个答案中如何工作的文档。

iOS - AWS MobileHub sign in with developer authenticated provider

更新 4:

如果您想访问 AWS 服务,则需要执行更多步骤

事实证明,这不会让您使用 Cognito 联合身份进行身份验证(身份浏览器上的“登录”计数保持为 0)。要解决此问题,您需要建立一个凭据提供程序并执行“credentialsProvider.getIdentityId”。之后登录将显示为肯定,您可以根据您的身份验证角色从 AWS 获取服务。

如果您尝试对移动应用程序进行 Authenticated 和 UnAuthenticated 访问,则需要创建 AWSAnonymousCredentialsProvider(在单独的服务配置中)。然后您在注销时 self.credentialsProvider?.invalidateCachedTemporaryCredentials() 和 self.credentialsProvider?.clearCredentials() 并使用匿名服务配置再次执行 getidentityid ,您将获得一个匿名 ID。 (注意:我发现如果您在凭据提供程序上清除钥匙串(keychain),每次用户注销时它都会以一个新 ID 开头,这可能会很快消耗掉您的 50,000 个免费 ID。)

更新 3:

在 Swift 中上传了适用于 IOS 的 AWS 用户池的 github 示例应用程序。

https://github.com/BruceBuckland/signin

更新 2:

我终于让 AWS 用户池在 Swift 中正常工作

我的问题是每次身份验证开始时都是由不同 View Controller 中的身份验证失败引起的(我的错误)。我最终让他们中的一群人在等待完成返回,而这些返回从未出现,并且 API 是“无声的”(没有显示任何错误)。 API 不会注意到它被多次启动(每次由不同的 viewController 启动),因此它会默默地一遍又一遍地登录。原始帖子中没有足够的代码来查看您是否遇到同样的问题。

你必须小心,AWS 示例代码(在 Objective-C 中)有两个导航 Controller ,代码重用了它们。我不喜欢示例应用程序在身份验证委托(delegate)开始之前闪烁登录 View Controller 的方式,我试图在 swift 版本中改进它,这导致了我的问题。

AWS 用户池 API 设置为使用 Storyboard或应用程序结构,其工作方式如下:

1) 您的应用假定它已登录,然后触发委托(delegate),如果未登录,则触发身份验证和登录屏幕。

2)在原始登录 View Controller pool.currentUser() 不足以进行身份​​验证,API 只会在您执行更多操作时触发委托(delegate)(在我的情况下为 user.getDetails())。

3) 通过 didCompletePasswordAuthenticationStepWithError 完成认证。如果您收到身份验证(或其他)错误并且成功进行身份验证,则会调用此委托(delegate)方法。在认证成功的情况下,NSError 为零,所以它应该声明为 NSError?在委托(delegate)中(这会导致警告)。 API 是测试版,他们可能会解决这个问题。

4) 另一个小“问题”,对你来说可能很明显,它捕获了我,当你在控制台中定义你的用户池时,你指定了允许的应用程序,这些应用程序中的每一个都有不同的客户端 ID 字符串字符串。 (我只是将相同的东西插入示例中)效果不佳(但不报告错误)。 API 需要报告部门的一些工作。它在工作时非常冗长,但如果您传递错误的客户端字符串,则什么也不说。此外,如果您(像我一样)从不同的 View Controller 调用 API,它似乎什么也没说。它只是从不同的 View Controller 获取每个新的身份验证请求并且什么也不说。

无论如何,它现在有效。我希望这有助于解决您的问题。

更新:

我终于得到了 getPasswordAuthenticationDetails 来执行。

事实证明,直到当前用户的 user.getDetails 才会执行它(即使没有当前用户)。

所以
let user = appDelegate.pool!.currentUser()
let details = user!.getDetails()

将导致在第二行执行 getPasswordAuthenticationDetails 回调。

AWS UserPool 的概念似乎是我们编写了一个假设我们有一个登录用户的应用程序。我们从该用户那里获取详细信息(例如在初始 View Controller 中),如果我们没有用户,则委托(delegate)将被启动。

IOS 上用户池的 AWS 文档缺少一些重要的概念页面。这些页面包含在(否则并行)Android 文档中。我承认我仍然在努力让用户池快速工作(现在几天),但是阅读 Android 文档的“主要类”和“关键概念”部分对我来说澄清了很多。我不明白为什么从 IOS 文档中省略了它。

关于ios - iOS (Swift) 应用程序中的 AWS Cognito 用户池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37176334/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com