应用程序重新启动后AWS ExpiredTokenException

我正在构建一个iOS(Swift)应用程序,使用AWS作为开发人员身份validation身份的后端。 一切正常,直到我关闭应用程序,保留一段时间,然后重新启动。 在这种情况下,我经常(但并非总是)在尝试从AWS检索数据时收到ExpiredTokenException错误。

这是我的代码:

class DeveloperAuthenticatedIdentityProvider: AWSAbstractCognitoIdentityProvider { var _token: String! var _logins: [ NSObject : AnyObject ]! override var token: String { get { return _token } } override var logins: [ NSObject : AnyObject ]! { get { return _logins } set { _logins = newValue } } override func getIdentityId() -> AWSTask! { if self.identityId != nil { return AWSTask(result: self.identityId) } else { return AWSTask(result: nil).continueWithBlock({ (task) -> AnyObject! in if self.identityId == nil { return self.refresh() } return AWSTask(result: self.identityId) }) } } override func refresh() -> AWSTask! { let apiUrl = "https://url-goes-here" // call my server to retrieve an OpenIdToken request.GET(apiUrl, parameters: nil, progress: nil, success: { (task: NSURLSessionDataTask, response: AnyObject?) -> Void in let tmp = NSMutableDictionary() tmp.setObject("temp", forKey: "ExampleApp") self.logins = tmp as [ NSObject : AnyObject ] let jsonDictionary = response as! NSDictionary self.identityId = jsonDictionary["identityId"] as! String self._token = jsonDictionary["token"] as! String awstask.setResult(response) }, failure: { (task: NSURLSessionDataTask?, error: NSError) -> Void in awstask.setError(error) } ) return awstask.task } } 

在AppDelegate中:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let identityProvider = DeveloperAuthenticatedIdentityProvider() // set default service configuration let credentialsProvider = AWSCognitoCredentialsProvider(regionType: cognitoRegion, identityProvider: identityProvider, unauthRoleArn: unauthRole, authRoleArn: authRole) let configuration = AWSServiceConfiguration(region: defaultServiceRegion, credentialsProvider: credentialsProvider) AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration // set service configuration for S3 (my bucket is located in a different region to my Cognito and Lambda service) let credentialsProviderForS3 = AWSCognitoCredentialsProvider(regionType: cognitoRegion, identityProvider: identityProvider, unauthRoleArn: unauthRole, authRoleArn: unauthRole) let awsConfigurationForS3 = AWSServiceConfiguration(region: s3ServiceRegion, credentialsProvider: credentialsProviderForS3) AWSS3TransferUtility.registerS3TransferUtilityWithConfiguration(awsConfigurationForS3, forKey: "S3") return true } 

这篇文章表明Cognito令牌已经过期,由开发人员手动刷新。 这似乎过于复杂,因为它需要设置定时刷新定时器,处理应用程序关闭和重新启动以及处理刷新过程中发生的AWS请求。 有更简单的方法吗? 例如,是否可以让AWS SDK在尝试使用过期令牌查询服务器时自动调用刷新?

任何帮助,将不胜感激。 我正在使用AWS SDK for iOS的2.3.5版。

适用于iOS 2.4.x的AWS Mobile SDK有一个名为AWSIdentityProviderManager的新协议。 它有以下方法:

 /** * Each entry in logins represents a single login with an identity provider. * The key is the domain of the login provider (eg 'graph.facebook.com') and the value is the * OAuth/OpenId Connect token that results from an authentication with that login provider. */ - (AWSTask *> *)logins; 

符合此协议的对象的责任是在请求时返回有效的logins字典。 由于此方法是异步的,因此如果缓存的令牌已过期,则可以在其中进行网络调用。 实现取决于您,但在许多情况下, AWSIdentityProviderManager管理多个AWSIdentityProvider ,聚合它们并返回logins字典。

不幸的是,开发人员刷新令牌是唯一的方法。

我同意,如果AWS SDK处理这个问题,应用程序开发人员会更简单,但CrdentialsProvider的设计方式应该是所有提供程序的通用方式。 例如,如果有人想使用Facebook作为提供者,则AWS SDK将无法自行处理刷新,开发人员将无法在其应用中处理该问题。 保持SDK的刷新流程使我们能够保持CredentialsProvider的通用性。