问题描述
我正在构建一个iOS(Swift)应用程序,使用AWS作为开发人员身份验证身份的后端。一切正常,直到我关闭应用程序,保留一段时间,然后重新启动。在这种情况下,我经常(但并非总是)在尝试从AWS检索数据时收到ExpiredTokenException错误。
I'm building an iOS (Swift) app using AWS as the backend with Developer Authenticated Identities. Everything works fine until I close the app, leave it for a while and then relaunch. In this scenario I often, but not always, receive ExpiredTokenException errors when trying to retrieve data from AWS.
这是我的代码:
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中:
And in the 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在尝试使用过期令牌查询服务器时自动调用刷新?
This post suggests that the Cognito token has expired and it is up to the developer to manually refresh. This seems overly complex as it would require setting a timer to refresh regularly, handling app closures and relaunches and handling AWS requests that occur while the refresh is taking place. Is there a simpler way? For example, is it possible to have the AWS SDK automatically call refresh whenever it attempts to query the server using an expired token?
任何帮助都将不胜感激。我正在使用AWS SDK for iOS的2.3.5版。
Any help would be appreciated. I'm using version 2.3.5 of the AWS SDK for iOS.
推荐答案
适用于iOS 2.4.x的AWS Mobile SDK一种叫做。它有以下方法:
The AWS Mobile SDK for iOS 2.4.x has a new protocol called AWSIdentityProviderManager
. It has the following method:
/**
* Each entry in logins represents a single login with an identity provider.
* The key is the domain of the login provider (e.g. 'graph.facebook.com') and the value is the
* OAuth/OpenId Connect token that results from an authentication with that login provider.
*/
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins;
符合此协议的对象的责任是返回有效的登录
字典,无论何时请求。由于此方法是异步的,因此如果缓存的令牌已过期,则可以在其中进行网络调用。实现取决于您,但在许多情况下, AWSIdentityProviderManager
管理多个 s,汇总它们并返回登录
字典。
The responsibility of an object conforming to this protocol is to return a valid logins
dictionary whenever it is requested. Because this method is asynchronous, you can make networking calls in it if the cached token is expired. The implementation is up to you, but in many cases, AWSIdentityProviderManager
manages multiple AWSIdentityProvider
s, aggregates them and return the logins
dictionary.
这篇关于应用程序重新启动后AWS ExpiredTokenException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!