AWS Amplify iOS SDK : FederatedSignIn Failed to retrieve authorization token on Amplify.API.post

Viewed 250

I've been working with the Amplify SDK to get federatedSignIn working with my iOS app with "Sign in with Apple" and Cognito to eventually make calls to API Gateway / Lambda functions.

TL;DR : My access token does not appear to be "automatically included in outbound requests" to my API as per the last paragraph of this section of the docs : Cognito User pool authorization

I have successfully authenticated using the tutorial found here Authentication Getting Started and other various Youtube videos on the Amazon Web Services channel.

Upon successful sign in through Apple I'm given an ASAuthorizationAppleIDCredential object. This contains the user field (token) which I pass to the Amplify.Auth class using the following Swift code :

func signIn (with userId: String)
{
    guard
        let plugin = try? Amplify.Auth.getPlugin(for: AWSCognitoAuthPlugin().key),
        let authPlugin = plugin as? AWSCognitoAuthPlugin,
        case .awsMobileClient (let client) = authPlugin.getEscapeHatch()
    else
    {
        return
    }
    
    client.federatedSignIn(providerName: AuthProvider.signInWithApple.rawValue, token: userId) { (state, error) in
        
        if let unwrappedError = error
        {
            print (unwrappedError)
        }
        else if let unwrappedState = state
        {
            print ("Successful federated sign in:", unwrappedState)
        }
    }
}

All appears to be successful and to double check I use the following bit of code to ensure I'm authorized :

func getCredentialsState (for userId:String)
{
    let provider = ASAuthorizationAppleIDProvider()
    
    provider.getCredentialState(forUserID: userId) { (credentialsState, error) in
        
        if let unwrappedError = error
        {
            print (unwrappedError)
        }
        
        switch credentialsState
        {
        case .authorized:
            print ("User Authorized")
        case .notFound, .revoked:
            print ("User Unauthenticated")
        case .transferred:
            print ("User Needs Transfer")
            
        @unknown default:
            print ("User Handle new use cases")
        }
    }
}

In the console I see "User Authorized" so everything appears to be working well.

However when I then go to make a call to Amplify.API.post I get the following error:

[Amplify] AWSMobileClient Event listener - signedOutFederatedTokensInvalid Failed APIError: Failed to retrieve authorization token. Caused by: AuthError: Session expired could not fetch cognito tokens Recovery suggestion: Invoke Auth.signIn to re-authenticate the user

My function for doing the POST is as follows :

func postTest ()
{
    let message = #"{'message": "my Test"}"#
    let request = RESTRequest (path: "/test", body: message.data(using: .utf8))
            
    Amplify.API.post (request:request)
    {
        result in switch result
        {
        case .success(let data):
            let str = String (decoding: data, as: UTF8.self)
            print ("Success \(str)")
            
        case .failure(let apiError):
            print ("Failed", apiError)
        }
    }
}`

I then went into the API Gateway UI and changed the generated Method Request on my resource from AWS IAM to my Cognito User Pool Authorizer thinking this was the issue. I also changed the awsAPIPlugin authorizationType to "AMAZON_COGNITO_USER_POOLS" in my amplifyconfiguration.json file. This unfortunately did not have any affect.

I've seen posts such as this issue User is not created in Cognito User pool for users logging in with Google federated login #1937 where people discuss the problem of having to to use a web ui to bring up the social sign in. I understand that Apple will reject your app sometimes for this. Therefore this is not a solution.

I then found this post which seems to resolve the issue however this appears to use the old version of the SDK? Get JWT Token using federatedSignIn #1276

I'm not great with Swift (I'm still an Objective C expert, but am slowly learning Swift) so I'm uncertain which path to go here and whether this is actually a solution? It does seem to be quite more complicated than the function I have that does my POST? The RESTRequest does seem to be a simple and easy solution but I'm uncertain how to pass it the Authorization token (or even how to get the token if it is needed here).

However, everything I've read about the SDK is that the authorization should be handled automatically in the background according the docs in my first link above. Specifically pointed out, again, here : Cognito User pool authorization. The last paragraph here states

With this configuration, your access token will automatically be included in outbound requests to your API, as an Authorization header.

Therefore, what am I missing here as this does not appear to automatically include my access token to my outbound requests to my API?

0 Answers
Related