iOS恢复时,AWS Cognito / Gatway API调用失败

时间:2016-11-10 11:24:19

标签: amazon-web-services amazon-cloudfront aws-api-gateway amazon-cognito

我有一个使用AWS Gateway API和AWS Cognito的Swift应用程序。 它使用AWS iOS SDK 2.4.9。

我的应用程序大多数时间都会进行身份验证,并且可以成功从我的AWS服务中检索内容。

但是,如果在休眠几小时后进行恢复,我会看到以下内容:

  • 该应用成功恢复其AWS Cognito会话
  • 但是对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 { …

0 个答案:

没有答案