我有一个使用AWS Gateway API和AWS Cognito的Swift应用程序。 它使用AWS iOS SDK 2.4.9。
我的应用程序大多数时间都会进行身份验证,并且可以成功从我的AWS服务中检索内容。
但是,如果在休眠几小时后进行恢复,我会看到以下内容:
但是对Gateway API的调用报告:
错误Domain = com.amazonaws.AWSAPIGatewayErrorDomain Code = 1"(null)"的UserInfo = {HTTPBody = { entries =>
0:X-Cache = {contents ="来自云端的错误"}
1:Content-Type = {contents =" application / json"}
2:x-amzn-ErrorType = {contents =" InvalidSignatureException"}
3:x-amzn-RequestId = {contents =" 8495fa1c-a737-11e6-83d0-31533a047a70"}
4:Via =
2ebb8]> {contents =" 1.1 699f29706ac19519e0b631e243565331.cloudfront.net(CloudFront)"}
6 : Date = <CFString 0x1742445c0 [0x1ac02ebb8]>{contents = "Thu, 10 Nov 2016 11:19:17 GMT"}
10 : Content-Length = 78
11 : X-Amz-Cf-Id = <CFString 0x174095db0 [0x1ac02ebb8]>{contents = "AlLCIYF8SYXUt2xV4yMdzmQw6t_5ykLBLjN1zE4eOxNgmfo91RySfQ=="}
12 : Connection = <CFString 0x174220560 [0x1ac02ebb8]>{contents = "keep-alive"}
}}
如果我尝试iOS SDK 2.4.11,则错误消息将更改为:
message = "Credential should be scoped to correct service: 'execute-api'. ";
},HTTPHeaderFields = {type = immutable dict,count = 9,
"Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x17405b210 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}, NSErrorFailingURLStringKey=(null)/MY_APIG_FUNCTION, NSErrorFailingURLKey=(null)/MY_APIG_FUNCTION, NSLocalizedDescription=unsupported URL}
在两种情况下都应该具有有效值的(null)。
我有一个``用于身份验证。
class CustomIdentityProviderManager: NSObject, AWSIdentityProviderManager {
var tokens : [NSObject : AnyObject]?
init(tokens: [NSObject : AnyObject]) {
self.tokens = tokens
}
@objc func logins() -> AWSTask {
return AWSTask(result: tokens)
}
}
class LoginManager {
var credentialsProvider : AWSCognitoCredentialsProvider?
init() {
// Initialize Amazon Cognito service manager with poolId and region type
self.credentialsProvider = AWSCognitoCredentialsProvider(regionType:AWSRegionType.USEast1, identityPoolId:Constants.CognitoIdentityPoolId)
let configuration = AWSServiceConfiguration(region:AWSRegionType.USEast1, credentialsProvider:self.credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
}
func completeLogin(token : A0Token, _ profile: A0UserProfile, _ success : () -> (), _ failure : (NSError) -> ()) {
// After successful Auth0 login perform Amazon login
doAmazonLogin(token.idToken, success: success, failure)
// Store profile and token in keychain
Application.sharedInstance.storeToken(token, profile: profile)
}
func doAmazonLogin(idToken: String, success : () -> (), _ failure : (NSError) -> ()) {
var task: AWSTask?
// Initialize clients for new idToken
if self.credentialsProvider?.identityProvider.identityProviderManager == nil || idToken != Application.sharedInstance.retrieveIdToken() {
let logins = [Constants.CognitoIDPUrl: idToken]
task = self.initializeClients(logins)
} else {
// Use existing clients
self.credentialsProvider?.invalidateCachedTemporaryCredentials()
task = self.credentialsProvider?.getIdentityId()
}
// Make login
task!.continueWithBlock { (task: AWSTask!) -> AnyObject! in
if (task.error != nil) {
failure(task.error!)
} else {
// the task result will contain the identity id
let cognitoId:String? = task.result as? String
// Store Cognito token in keychain
Application.sharedInstance.storeCognitoToken(cognitoId)
success()
}
return nil
}
}
func initializeClients(logins: [NSObject : AnyObject]?) -> AWSTask? {
let manager = CustomIdentityProviderManager(tokens: logins!)
self.credentialsProvider?.setIdentityProviderManagerOnce(manager)
return self.credentialsProvider?.getIdentityId()
}
// enhanced Auth0 code to refresh tokenId if it has expired
func resumeLogin(success : () -> (), _ failure : (NSError) -> ()) {
let idToken = Application.sharedInstance.retrieveIdToken()
if let idToken = idToken {
if Application.sharedInstance.isTokenIdExpired(idToken) {
let refreshSuccess = {(token:A0Token!) -> () in
self.doAmazonLogin(token.idToken, success: success, failure)
Application.sharedInstance.storeToken(token)
success()
}
let refreshFail = {(error:NSError!) -> () in
Application.sharedInstance.logout()
failure(error)
}
if let refreshToken = Application.sharedInstance.retrieveRefreshToken() {
A0Lock.sharedLock().apiClient().fetchNewIdTokenWithRefreshToken(refreshToken, parameters: nil, success: refreshSuccess, failure: refreshFail)
} else {
let error = NSError(domain: "com.auth0", code: 0, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Something went wrong", comment: "This is an error")])
failure(error)
}
} else {
doAmazonLogin(idToken, success: success, failure)
}
} else {
let error = NSError(domain: "com.auth0", code: 0, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Something went wrong", comment: "This is an error")])
failure(error)
}
}
}
在App启动时,我调用resumeLogin()。在恢复期间,这成功但是当我尝试进行APIG呼叫时,它有时会失败。特别是在使用app后数小时。
我这样调用我的AWS APIG服务:
let client = XXXXxxxxClient.defaultClient()
client.questionGet().continueWithBlock { …