aws-amplify / aws-sdk-ios

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

How to refresh AWSCredentials? #1949

Closed phanchutoan closed 10 months ago

phanchutoan commented 4 years ago

Related to this issue https://github.com/aws-amplify/aws-sdk-ios/issues/1691

I am using @palpatim solution to refresh aws credential

[[[[[AWSS3 defaultS3] configuration] credentialsProvider] credentials] waitUntilFinished];

But some time when credential expire, it can not be refreshed.

As I debug in to SDK, App run into waiting for google sdk.

AWSCredentialsProvider.m, Line 625

if (self.isRefreshingCredentials) {
                // Waits up to 60 seconds for the Google SDK to refresh a token.
                if (dispatch_semaphore_wait(self.semaphore, dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC)) != 0) {
                    NSError *error = [NSError errorWithDomain:AWSCognitoCredentialsProviderErrorDomain
                                                         code:AWSCognitoCredentialsProviderCredentialsRefreshTimeout
                                                     userInfo:nil];
                    return [AWSTask taskWithError:error];
                }
            }

What can I do in this case? As we can not use the AWS credential any more (create pre-signed url request fail)

It seem that restart the app fixed the problem.

P/s: We also develop an android version of our app using aws android sdk. It is not neccessary to refresh credential there.

royjit commented 4 years ago

@phanchutoan Few questions:

phanchutoan commented 4 years ago

I am not using user pool, I am using identity pool with developer authenticated identities.

phanchutoan commented 4 years ago

[[[[[AWSS3 defaultS3] configuration] credentialsProvider] credentials] waitUntilFinished]; works some time but not always, as i said above, when i try to debug in to sdk, it stuck at // Waits up to 60 seconds for the Google SDK to refresh a token.

ghani-ma commented 4 years ago

@palpatim @royjit any updates on this issue? For more detail information about this issue:

State your question Refresh Credentials always ends up waitinig for Google SDK

Which AWS Services are you utilizing? AWSCognito AWSS3

Environment

SDK Version: 2.13.4 Dependency Manager: Cocoapods Swift Version : 5.0

Device Information: Device: iPhone XR iOS Version: iOS 13.5.1

Previous questions:

I'm using Developer Authenticated Identities

class DeveloperAuthenticatedIdentityProvider: AWSCognitoCredentialsProviderHelper {
    convenience override init() {
        self.init(regionType: .APNortheast1, identityPoolId: AWS.identityPool, useEnhancedFlow: true, identityProviderManager: nil)
    }

    override func token() -> AWSTask<NSString> {
        let cognitoToken = DefaultStorage.cognitoToken! as NSString
        identityId = DefaultStorage.cognitoId
        return AWSTask(result: cognitoToken)
    }
}

With AWSServiceManager initialization:

func configureAWSServiceManager() {
    let devAuth = DeveloperAuthenticatedIdentityProvider()
    let cognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType: .APNortheast1, identityProvider: devAuth)
    let configuration = AWSServiceConfiguration(region: .APNortheast1, credentialsProvider: cognitoCredentialsProvider)
    AWSServiceManager.default()?.defaultServiceConfiguration = configuration
}

We're builing an app that show many photos using UICollectionView, the photo's image will be displayed using Presigned URL if it's not cached before on the device.

After some minutes the app runs, when creating PresignedURL the library will return AWSCognitoCredentialsProviderErrorDomain code 4

as @palpatim 's solution, by calling [[[[[AWSS3 defaultS3] configuration] credentialsProvider] credentials] waitUntilFinished] seems work, but when app entered to background for some minutes (about 8~12 minutes) and opens the app, there's a possibility that the library always waiting 60s for Google SDK to refresh a token. it's always ends up on AWSCredentialsProvider.m: Line 626 inside this function: AWSTask<AWSCredentials *> *)credentialsWithCancellationToken:(AWSCancellationTokenSource *) cancellationTokenSource and will lead to throw an error AWSCognitoCredentialsProviderErrorDomain code 4 : AWSCognitoCredentialsProviderInvalidCognitoIdentityToken

if (self.isRefreshingCredentials) {
    // Waits up to 60 seconds for the Google SDK to refresh a token.
    if (dispatch_semaphore_wait(self.semaphore, dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC)) != 0) {
        NSError *error = [NSError errorWithDomain:AWSCognitoCredentialsProviderErrorDomain
                                             code:AWSCognitoCredentialsProviderCredentialsRefreshTimeout
                                         userInfo:nil];
        return [AWSTask taskWithError:error];
    }
}
royjit commented 1 year ago

Apologies for loosing track on this issue. I am trying to see if this logic work without the waiting for Google, preliminary testing looks promising. I have attached a branch here for testing https://github.com/aws-amplify/aws-sdk-ios/tree/royjit.credentialsproviderfix

If you still facing this issue could you please try this this branch and see if the issue exists?

ghani-ma commented 1 year ago

Hi @royjit , it's been 2 years and I really appreciate your follow up. I've change my podfile like below.

platform :ios, '13.0'
use_frameworks!
def install_pods
    pod 'AWSCore', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
    pod 'AWSCognito'
    pod 'AWSS3'
end

However it seems the AWSCognito version is not compatible with the branch you pushed.

[!] CocoaPods could not find compatible versions for pod "AWSCore":
  In snapshot (Podfile.lock):
    AWSCore (from `https://github.com/aws-amplify/aws-sdk-ios.git`, branch `royjit.credentialsproviderfix`)

  In Podfile:
    AWSCognito was resolved to 2.1.0, which depends on
      AWSCore (~> 2.1.0)

    AWSCore (from `https://github.com/aws-amplify/aws-sdk-ios.git`, branch `royjit.credentialsproviderfix`)

Could you assist me which version should I use for AWSCognito and AWSS3 to handle that error?

royjit commented 1 year ago

Will you be able to point other pods as well to the fix?

pod 'AWSCore', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
pod 'AWSCognito', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
 pod 'AWSS3', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
ghani-ma commented 1 year ago

Hi @royjit. I have tried to set the podfile like above. However it's still no luck when installing the pod since the Unable to find a specification for 'AWSCognito'error occurs. Could you assist me regarding why this error occurs?

Podfile:

def install_pods
    pod 'AWSCore', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
    pod 'AWSCognito', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
    pod 'AWSS3', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
end

Console Output:

-> Pre-downloading: `AWSCognito` from `https://github.com/aws-amplify/aws-sdk-ios.git`, branch `royjit.credentialsproviderfix`
  $ /usr/bin/git ls-remote https://github.com/aws-amplify/aws-sdk-ios.git royjit.credentialsproviderfix
  84f634107c7bf0c0199b374b9bf75ae7c2301458  refs/heads/royjit.credentialsproviderfix
 > Git download
 > Git download
     $ /usr/bin/git clone https://github.com/aws-amplify/aws-sdk-ios.git
     /var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221107-78023-1cmkjxs --template=
     Cloning into '/var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221107-78023-1cmkjxs'...
   $ /usr/bin/git -C /var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221107-78023-1cmkjxs checkout --quiet
   84f634107c7bf0c0199b374b9bf75ae7c2301458
[!] Unable to find a specification for 'AWSCognito'.
phantumcode commented 1 year ago

Could you try reset the cocoapod cache and try again?

rm -rf "${HOME}/Library/Caches/CocoaPods"
rm -rf "`pwd`/Pods/"
pod update
ghani-ma commented 1 year ago

Hi @phantumcode. I have tried above steps to reset the cocoapods. However, it's still no luck when updating the pods.

rm -rf "${HOME}/Library/Caches/CocoaPods"
rm -rf "`pwd`/Pods/"
pod update --verbose
Update all pods
  Preparing

Updating local specs repositories
  CDN: trunk Relative path: CocoaPods-version.yml exists! Returning local because checking is only performed in repo update

Updating spec repo `master`

Updating spec repo `artsy`

Analyzing dependencies

Inspecting targets to integrate
  Using `ARCHS` setting to build architectures of target `Pods-Fueru`: (``)

Finding Podfile changes
  A AWSCore
  M AWSCognito
  M AWSS3

Fetching external sources
-> Pre-downloading: `AWSCognito` from `https://github.com/aws-amplify/aws-sdk-ios.git`, branch `royjit.credentialsproviderfix`
  $ /usr/bin/git ls-remote https://github.com/aws-amplify/aws-sdk-ios.git royjit.credentialsproviderfix
  84f634107c7bf0c0199b374b9bf75ae7c2301458  refs/heads/royjit.credentialsproviderfix
 > Git download
 > Git download
     $ /usr/bin/git clone https://github.com/aws-amplify/aws-sdk-ios.git /var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221204-15385-1hjbo7c --template=
     Cloning into '/var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221204-15385-1hjbo7c'...
   $ /usr/bin/git -C /var/folders/5f/pnvqw1g156n5m7vyz7623mhm0000gn/T/d20221204-15385-1hjbo7c checkout --quiet 84f634107c7bf0c0199b374b9bf75ae7c2301458
[!] Unable to find a specification for 'AWSCognito'.

/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/external_sources/abstract_external_source.rb:124:in `block in pre_download'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/user_interface.rb:86:in `titled_section'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/external_sources/abstract_external_source.rb:113:in `pre_download'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/external_sources/downloader_source.rb:13:in `fetch'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:993:in `fetch_external_source'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:972:in `block (2 levels) in fetch_external_sources'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:971:in `each'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:971:in `block in fetch_external_sources'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/user_interface.rb:64:in `section'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:970:in `fetch_external_sources'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer/analyzer.rb:117:in `analyze'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer.rb:416:in `analyze'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer.rb:241:in `block in resolve_dependencies'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/user_interface.rb:64:in `section'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer.rb:240:in `resolve_dependencies'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/installer.rb:161:in `install!'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/command/update.rb:63:in `run'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/claide-1.1.0/lib/claide/command.rb:334:in `run'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/lib/cocoapods/command.rb:52:in `run'
/Users/-/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/cocoapods-1.11.3/bin/pod:55:in `<top (required)>'
/Users/-/.rbenv/versions/2.7.1/bin/pod:25:in `load'
/Users/-/.rbenv/versions/2.7.1/bin/pod:25:in `<main>'
royjit commented 1 year ago

Apologies for losing track on this. I see that you are depending on a deprecated pod - AWSCognito. If you are trying to use Cognito User pool you should be using AWSCognitoIdentityProvider. So does updating the podfile to the below should work:

pod 'AWSCore', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
pod 'AWSCognitoIdentityProvider', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
pod 'AWSS3', :git => 'https://github.com/aws-amplify/aws-sdk-ios.git', :branch => 'royjit.credentialsproviderfix'
ghani-ma commented 1 year ago

Hi @royjit, I tried using that podfile and it worked well. After keeping the app in the background for several hours/days and then navigating to the foreground, I was still able to retrieve the Presigned URL from Cognito. It seems that I can say the royjit.credentialsproviderfix branch fixed the issue.

However, based on the changes you have made, is it safe to just remove the waiting credential things?

tenshiAMD commented 10 months ago

@ghani-ma @royjit I encountered the same issue. This commit seems to be the proper fix as this is already merged in the main branch. The fix was released in version https://github.com/aws-amplify/aws-sdk-ios/releases/tag/2.28.2. IMHO, I would prefer to use the main branch and released version changes than use the workaround branch mentioned above. Anyway, the information above was really helpful. Thanks a lot! 👍