aws-amplify / aws-sdk-ios

AWS SDK for iOS. For more information, see our web site:
https://aws-amplify.github.io/docs
Other
1.67k stars 877 forks source link

Cognito auth expires when app is in Background (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.) #1519

Closed bolak2 closed 4 years ago

bolak2 commented 5 years ago

Describe the bug A clear and concise description of what the bug is.

Hello, AWSers, I am using AWS amplify for authentication (Cognito) and S3 storage in my IOS swift app. However, I am having trouble uploading files to S3, if the app has been in the background for a while my app is unable to obtain an identity ID and therefore can not complete the upload.

To Reproduce Steps to reproduce the behavior: If the user were to sign in and let the app wait in the background for a few minutes (ex: 5mins), the user is now unable to upload files to S3, getting the following error:

Error: Obtaining an identity id in another thread failed or didn't complete within 5 seconds.
Error: The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)

As a result, the user now needs to sign out and sign back in, so that they may continue uploading video files to s3.

Which AWS service(s) are affected? AWSMobileClient, AWSS3, AWSAuthUI

Expected behavior A clear and concise description of what you expected to happen. I would expect AWS to refresh the tokens automatically after the app returns to the active state. My access token is set to expire every hour while my refresh token is valid for 24 hours. So my set up looks okay but doesn't work.

Environment(please complete the following information):

Device Information (please complete the following information): All iPhones

Additional context Add any other context about the problem here.

Here is what I have in my AppDelegate.swift:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // AWS Id config
        let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.USEast1,identityPoolId:config_identityID)
        let configuration = AWSServiceConfiguration(region:.USEast1, credentialsProvider:credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = configuration

I am using AWS Drop-in Auth for sign in:

    func showSignIn() {
        // Drop in Auth that handles sign in for users
        AWSMobileClient.sharedInstance()
            .showSignIn(navigationController: self.navigationController!,
                        signInUIOptions: SignInUIOptions(
                            canCancel: false,
                            logoImage: UIImage(named: "PMA background"),
                            backgroundColor: UIColor.black)) { (signInState, error) in
                                //handle results and errors

                                if let signInState = signInState {
                                    print("logged in!", signInState)
                                    self.getCredentials()

                                } else {
                                    print("error logging in: \(error!.localizedDescription)")
                                }
        }
    }

Reference: https://aws-amplify.github.io/docs/ios/storage

bolak2 commented 5 years ago

@rohandubal Anyway you can help?

afriedmanGlacier commented 5 years ago

We are seeing something similar trying to download from S3 (we are not using AWSMobileClient, but using AWSCognitoCredentialsProvider and AWSS3 directly).

If we initially login, the download works fine. But after the session expires, it does not refresh and we need to explicitly log out and then back in for it to work.

bolak2 commented 5 years ago

Exactly what's going on with us, perhaps there is a way to manually use the refresh token to get a new access token?

royjit commented 4 years ago

We did some fixes around getIdentity, this would potential fix your issue. We released this in https://github.com/aws-amplify/aws-sdk-ios/releases/2.11.0

Could you please try the new SDK and see if that fixes your issue?

bolak2 commented 4 years ago

Hey royjit, thats great to hear! I was able to fix the issue on my end in amplify 2.9. The trick was to include S3TransferUtility in the awsconfiguration.json file:

{
    "UserAgent": "auto",
    "Version": "0.1.0",
    "IdentityManager": {
        "Default": {}
    },
    "CredentialsProvider": {
        "CognitoIdentity": {
            "Default": {
                "PoolId": "***",
                "Region": "****"
            }
        }
    },
    "CognitoUserPool": {
        "Default": {
            "PoolId": "***",
            "AppClientId": "***",
            "AppClientSecret": "***",
            "Region": "****"
        }
    },
    "S3TransferUtility": {
        "Default": {
            "Bucket": "***-****",
            "Region": "**-****-*"
        }
    }
}

This solved the refresh access token issue. Maybe add this to your documentation? When I created this issue back in May there were almost no resources I could use to figure out the problem until I came across a DynamoDB example.

royjit commented 4 years ago

Glad to hear that it fixed your issue. Did you use https://aws-amplify.github.io/docs/ios/storage for setting up storage for your project?

stale[bot] commented 4 years ago

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

dkurtagic commented 4 years ago

Hello colleagues,

@royjit I have a similar issue with the token refresh but with the AWS SDK generated from API Gateway. When the auth token expires after 1 hour, I am getting NSURLErrorDomain: -1003 Optional("The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)")

My awsconfiguration.js looks like this: { "UserAgent": "aws-amplify-cli/0.1.0", "Version": "0.1.0", "IdentityManager": { "Default": {} }, "CredentialsProvider": { "CognitoIdentity": { "Default": { "PoolId": "somepoolid", "Region": "eu-central-1" } } }, "CognitoUserPool": { "Default": { "PoolId": "somepoolid", "AppClientId": "someclientid", "AppClientSecret": "somesecret", "Region": "eu-central-1" } }, "Auth": { "Default": { "authenticationFlowType": "CUSTOM_AUTH" } } }

in didFinishLaunchingWithOptions this is how I configure: ` let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.EUCentral1, identityPoolId: CognitoIdentityUserPoolId) let configuration = AWSServiceConfiguration(region: AWSRegionType.EUCentral1, credentialsProvider: credentialsProvider) AWSServiceManager.default().defaultServiceConfiguration = configuration

AWSMobileClient.default().initialize { (userState, error) in if let userState = userState { self.getTokens() } else if let error = error { print("error: (error.localizedDescription)") } } `

after I get the userState that user is logged in I tried to force token refresh to check if the tokens are returned correctly AWSMobileClient.default().getTokens { (tokens, error) in } and they are correct.

My generated AWS SDK client is possibly not getting refreshed tokens and returning "The operation couldn’t be completed. (com.amazonaws.AWSCognitoIdentityErrorDomain error 8.)" and on some endpoints: "Unauthenticated access is not supported for this identity pool."

This is my podfile.lock `PODS:

I am using " XXXXBackendClient.default(). " for all of my API Gateway calls to our Laravel backend endpoints. And this happens only when I all API gateway calls.

All of the calls to Cognito where I change user attributes are passing through successfully. Am I doing something wrong?

I would appreciate any hint very much. Thanks in advance!

BillBunting commented 4 years ago

@dkurtagic I have workarounds in place in an iOS app for the symptoms you report, and have been unable to upgrade the peer Android app for similar errors. I'm waiting this issue closely to see if there is any resolution. The symptoms are similar to what I reported here: https://github.com/aws-amplify/aws-sdk-android/issues/1003

futurealecks commented 4 years ago

Reopening because this is still an issue for us. In app tokens expiring fast and we're unable to extend the length @BillBunting @afriedmanGlacier