Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent/Incorrect behavior when fetching auth session without internet access #760

Closed
miguelflores1993 opened this issue Jul 28, 2021 · 24 comments
Assignees
Labels
auth Issues related to the Auth Category bug Something is not working; the issue has reproducible steps and has been reproduced fixed-in-release-candidate Issues that have been addressed in the current release-candidate branch platform-discrepancy Issues that result in inconsistent behavior between support platforms requires-android-fix This issue is the result of an underlying Amplify Android issue that needs to be fixed. requires-ios-fix This issue is the result of an underlying Amplify iOS issue that needs to be fixed.

Comments

@miguelflores1993
Copy link

my application is about an uber truck, where most of the road is OFFLINE.
but when he wants to make an offline request he skips that error.
Does anyone know how to apply it for offline mode?

error:
SessionExpiredException(message: Your session has expired., recoverySuggestion: Please sign in and reattempt the operation., underlyingException: null)

code:
CognitoAuthSession res = await Amplify.Auth.fetchAuthSession(options: CognitoSessionOptions(getAWSCredentials: true));

@haverchuck
Copy link
Contributor

haverchuck commented Jul 28, 2021

@flutteresbolivia Is this on Android or iOS? And is the refresh token actually valid?

@miguelflores1993
Copy link
Author

miguelflores1993 commented Jul 28, 2021

@flutteresbolivia ¿Es esto en Android o iOS? ¿Y el token de actualización es realmente válido?

android with Flutter 2.0,6.
sdk 30
Mobile: Samsumg S10 PLUS
android 11

About the token is that the phone is mostly without internet.

@haverchuck
Copy link
Contributor

@flutteresbolivia What is the expected behavior, exactly? A network exception?

@miguelflores1993
Copy link
Author

@flutteresbolivia ¿Cuál es el comportamiento esperado, exactamente? ¿Una excepción de red?

That the session does not expire and you can continue working with the local data of the phone, if you cannot find the internet.

@haverchuck
Copy link
Contributor

haverchuck commented Jul 28, 2021

@flutteresbolivia Are you attempting to work in a signed out state, with guest credentials from an identity pool? Or are you trying to use Datastore for offline functionality?

@offlineprogrammer
Copy link
Contributor

Hi @flutteresbolivia

Following up on this. If you are still experiencing an issue, please provide the info requested above.

Regards
Mo

@offlineprogrammer offlineprogrammer added the pending-close-response-required The issue will be closed if details necessary to reproduce the issue are not provided within 7 days. label Aug 30, 2021
@offlineprogrammer
Copy link
Contributor

Hey @flutteresbolivia

I am closing this issue for now as we didn't hear from you
We can reopen it if you are still facing the issue and when you provide details

Regards
Mo

@wasitu
Copy link

wasitu commented Sep 14, 2021

Please reopen this issue.
We still receive a SessionExpiredException error every time we go offline even though the session has not expired. If there is a network error, then I would like to receive a network error instead of a SessionExpiredException.

Right now, I cannot differentiate between a session really expiring (for which I would want to force a sign out) versus a network issue.

@offlineprogrammer offlineprogrammer added auth Issues related to the Auth Category and removed pending-close-response-required The issue will be closed if details necessary to reproduce the issue are not provided within 7 days. labels Sep 14, 2021
@fpabl0
Copy link

fpabl0 commented Oct 7, 2021

I have the same issue, even if I do Amplify.Auth.signOut(), the next time the exception is always SessionExpiredException instead of SignedOutException.

@miguelflores1993
Copy link
Author

Of course we would like that when there is no internet it does not return SessionExpiredException

If not more like a network error, it is difficult for me to control, please fix it

@Jordan-Nelson Jordan-Nelson added pending-triage This issue is in the backlog of issues to triage to-be-reproduced Issues that have not been reproduced yet, but have reproduction steps provided labels Mar 8, 2022
@Jordan-Nelson Jordan-Nelson self-assigned this Mar 8, 2022
@Jordan-Nelson
Copy link
Member

Jordan-Nelson commented Mar 8, 2022

Hello all - Apologies for the late update. It looks like this fell off our radar. It sounds like Auth APIs are throwing SessionExpiredException when there is no network, even if the session has not actually expired. I can attempt to reproduce this.

Are you seeing this on both iOS and Android, or just on one particular platform?

@gianmarcocalbi
Copy link

gianmarcocalbi commented Mar 9, 2022

Hello all - Apologies for the late update. It looks like this fell off our radar. It sounds like Auth APIs are throwing SessionExpiredException when there is not network, even if the session has not actually expired. I can attempt to reproduce this.

Are you seeing this on both iOS and Android, or just on one particular platform?

I am using the version 0.3.2 of the amplify plugin

Android

SessionExpiredException

iOS

UnknownException(message: Unexpected error occurred with message: An unknown error occurred, recoverySuggestion: This should not happen. There is a possibility that there is a bug if this error persists. Please take a look at https://github.com/aws-amplify/amplify-ios/issues to see if there are any existing issues that match your scenario, and file an issue with the details of the bug if there isn't. Issue encountered at:
file: /Users/marco/development/wayt/wayt_app/ios/Pods/Amplify/Amplify/Categories/Auth/Error/AuthError.swift
function: recoverySuggestion
line: 80, underlyingException: Impossibile completare l'operazione. (Errore com.amazon.cognito.AWSCognitoAuthErrorDomain -2000).)

## STACKTRACE
#0      AmplifyAuthCognitoMethodChannel.fetchAuthSession (package:amplify_auth_cognito/method_channel_auth_cognito.dart:249)
<asynchronous suspension>
#1      AmplifyAuthCognito.fetchAuthSession (package:amplify_auth_cognito/amplify_auth_cognito.dart:113)
<asynchronous suspension>

@Jordan-Nelson
Copy link
Member

@gianmarcocalbi - can you share the code that results in those errors as well as any steps to reproduce them?

I am not able to reproduce this with the following code:

CognitoAuthSession res = await Amplify.Auth.fetchAuthSession(
  options: CognitoSessionOptions(getAWSCredentials: true),
);

I have attempted the following:

  • Sign in
  • Turn network off
  • fetch session - works as expected (on both iOS and Android)
  • wait until session token expires
  • fetch session
    • On Android: I am not seeing an exception. The response doesn't have the user sub or the tokens though. This probably should throw an exception, but it doesn't seem to be.
    • On iOS: I get the following error: AuthException(message: A network error occured while trying to fetch user sub, recoverySuggestion: Try again with exponential backoff, underlyingException: The operation couldn’t be completed. (AmplifyPlugins.AWSCognitoAuthError error 21.))

From what I can see, there is an inconsistency between iOS and Android in the response when the network is offline and the session token has expired. However, I don't see a SessionExpiredException in either case.

This isn't a fix for the reported issue, but I want to note that Cognito set defaults session/refresh token expiration, and that these can be customized. I believe the defaults are 60 minutes for session token, and 30 days for refresh token. If you expect your users to be offline frequently and/or for long periods of time, you may want to consider adjusting the default session token expiration.

@Jordan-Nelson Jordan-Nelson added the pending-community-response Pending response from the issue opener or other community members label Mar 9, 2022
@gianmarcocalbi
Copy link

@gianmarcocalbi - can you share the code that results in those errors as well as any steps to reproduce them?

I am not able to reproduce this with the following code:

CognitoAuthSession res = await Amplify.Auth.fetchAuthSession(
  options: CognitoSessionOptions(getAWSCredentials: true),
);

I have attempted the following:

  • Sign in

  • Turn network off

  • fetch session - works as expected (on both iOS and Android)

  • wait until session token expires

  • fetch session

    • On Android: I am not seeing an exception. The response doesn't have the user sub or the tokens though. This probably should throw an exception, but it doesn't seem to be.
    • On iOS: I get the following error: AuthException(message: A network error occured while trying to fetch user sub, recoverySuggestion: Try again with exponential backoff, underlyingException: The operation couldn’t be completed. (AmplifyPlugins.AWSCognitoAuthError error 21.))

From what I can see, there is an inconsistency between iOS and Android in the response when the network is offline and the session token has expired. However, I don't see a SessionExpiredException in either case.

This isn't a fix for the reported issue, but I want to note that Cognito set defaults session/refresh token expiration, and that these can be customized. I believe the defaults are 60 minutes for session token, and 30 days for refresh token. If you expect your users to be offline frequently and/or for long periods of time, you may want to consider adjusting the default session token expiration.

I have tried to replicate using the v0.4.1 and following your steps and

  • for Android I get no exception and null tokens like you
  • for iOS (I am using a Simulator) I still get the UnknownException:
    1. I do SignIn
    2. fetchAuthSession to check that is works, and it does work
    3. close the app
    4. wait 6min (on cognito I have set ID token and Access token expiration = 5min)
    5. turn internet off
    6. launch the app
    7. fetchAuthSession
Unhandled Exception: UnknownException(message: Unexpected error occurred with message: An unknown error occurred, recoverySuggestion: This should not happen. There is a possibility that there is a bug if this error persists. Please take a look at https://github.com/aws-amplify/amplify-ios/issues to see if there are any existing issues that match your scenario, and file an issue with the details of the bug if there isn't. Issue encountered at:
file: /Users/gcalbi/workspace/wayt_app/ios/Pods/Amplify/Amplify/Categories/Auth/Error/AuthError.swift
function: recoverySuggestion
line: 80, underlyingException: The operation couldn’t be completed. (com.amazon.cognito.AWSCognitoAuthErrorDomain error -2000.))
#0      AmplifyAuthCognitoMethodChannel.fetchAuthSession (package:amplify_auth_cognito/method_channel_auth_cognito.dart:249:7)
<asynchronous suspension>
#1      AmplifyAuthCognito.fetchAuthSession (package:amplify_auth_cognito/amplify_auth_cognito.dart:113:17)

If I understand well, from your explanation, the issue is that

  1. the access token is expired
  2. amplify tries to use the refresh token to get a new valid access token
  3. the operation cannot be fulfilled due to the network being unreachable, so the exception occurs.

As you mentioned, iOS and Android behavior should be consistent, and in my opinion the exception should be more specific than AuthException, so that we can catch it and handle it properly.

@gianmarcocalbi
Copy link

gianmarcocalbi commented Mar 10, 2022

Now, after 1h, I have just launched the app on Android still with the phone in airplane mode (network off), and fetchAuthSession gave me SessionExpiredException, while 1h ago I was getting no exception but null tokens. I have no idea why, basically I did

  1. I do SignIn
  2. fetchAuthSession to check that it works, and it does work
  3. close the app
  4. wait 6min (on cognito I have set ID token and Access token expiration = 5min)
  5. turn internet off
  6. launch the app
  7. fetchAuthSession -> OK but with null tokens
  8. Wait longer (I have waited like 1h30m)
  9. launch the app
  10. fetchAuthSession -> SessionExpiredException
/amplify:flutter:auth_cognito(21430): SessionExpiredException
E/amplify:flutter:auth_cognito(21430): SessionExpiredException{message=Your session has expired., cause=null, recoverySuggestion=Please sign in and reattempt the operation.}
E/amplify:flutter:auth_cognito(21430): 	at com.amazonaws.amplify.amplify_auth_cognito.AuthCognito.prepareCognitoSessionFailure(AuthCognito.kt:622)
E/amplify:flutter:auth_cognito(21430): 	at com.amazonaws.amplify.amplify_auth_cognito.AuthCognito.onFetchAuthSession$lambda-18(AuthCognito.kt:386)
E/amplify:flutter:auth_cognito(21430): 	at com.amazonaws.amplify.amplify_auth_cognito.AuthCognito.lambda$uu-F3NQTLN2zVTYaQlc45ppd10Q(Unknown Source:0)
E/amplify:flutter:auth_cognito(21430): 	at com.amazonaws.amplify.amplify_auth_cognito.-$$Lambda$AuthCognito$uu-F3NQTLN2zVTYaQlc45ppd10Q.accept(Unknown Source:8)
E/amplify:flutter:auth_cognito(21430): 	at com.amplifyframework.auth.cognito.MobileClientSessionAdapter$3.onError(MobileClientSessionAdapter.java:194)
E/amplify:flutter:auth_cognito(21430): 	at com.amazonaws.mobile.client.internal.ReturningRunnable$1.run(ReturningRunnable.java:47)
E/amplify:flutter:auth_cognito(21430): 	at java.lang.Thread.run(Thread.java:923)
E/flutter (21430): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: SessionExpiredException(message: Your session has expired., recoverySuggestion: Please sign in and reattempt the operation., underlyingException: null)
E/flutter (21430): #0      AmplifyAuthCognitoMethodChannel.fetchAuthSession (package:amplify_auth_cognito/method_channel_auth_cognito.dart:249:7)
E/flutter (21430): <asynchronous suspension>
E/flutter (21430): #1      AmplifyAuthCognito.fetchAuthSession (package:amplify_auth_cognito/amplify_auth_cognito.dart:113:17)
E/flutter (21430): <asynchronous suspension>
E/flutter (21430): #2      _AltScreenState.build.<anonymous closure> (package:wayt_app/ui/alt_screen.dart:72:33)
E/flutter (21430): <asynchronous suspension>
E/flutter (21430): 

@Jordan-Nelson Jordan-Nelson removed the pending-community-response Pending response from the issue opener or other community members label Mar 10, 2022
@Jordan-Nelson
Copy link
Member

As you mentioned, iOS and Android behavior should be consistent, and in my opinion the exception should be more specific than AuthException, so that we can catch it and handle it properly.

I agree, we can mark this as a bug for a) the inconsistency, and b) the generic error opposed to a specific and helpful error

Now, after 1h, I have just launched the app on Android still with the phone in airplane mode (network off), and fetchAuthSession gave me SessionExpiredException

What is your refresh token expiration? I believe the lowest Cognito allows is 60 minutes. If you happen to have it set to 60 minutes, I think this would be expected since at this point your session and refresh token would have expired. If your refresh token is much higher, I wouldn't expect the behavior you are seeing.

@Jordan-Nelson Jordan-Nelson added the pending-community-response Pending response from the issue opener or other community members label Mar 10, 2022
@Jordan-Nelson Jordan-Nelson removed their assignment Mar 11, 2022
@gianmarcocalbi
Copy link

As you mentioned, iOS and Android behavior should be consistent, and in my opinion the exception should be more specific than AuthException, so that we can catch it and handle it properly.

I agree, we can mark this as a bug for a) the inconsistency, and b) the generic error opposed to a specific and helpful error

Now, after 1h, I have just launched the app on Android still with the phone in airplane mode (network off), and fetchAuthSession gave me SessionExpiredException

What is your refresh token expiration? I believe the lowest Cognito allows is 60 minutes. If you happen to have it set to 60 minutes, I think this would be expected since at this point your session and refresh token would have expired. If your refresh token is much higher, I wouldn't expect the behavior you are seeing.

For the test I did:

Refresh token expiration
30 day(s)

Access token expiration
5 minutes

ID token expiration
5 minutes

@Jordan-Nelson Jordan-Nelson removed the pending-community-response Pending response from the issue opener or other community members label Mar 14, 2022
@Jordan-Nelson Jordan-Nelson self-assigned this Mar 14, 2022
@Jordan-Nelson
Copy link
Member

@gianmarcocalbi - Okay, I am not sure what would be different between 5+ minutes and 1 hour. I'll see if I can reproduce this.

@Jordan-Nelson
Copy link
Member

Jordan-Nelson commented Mar 15, 2022

I am going to attempt to repro the exception you have seen after 1 hour, but regardless I am going to mark this as a bug and a platform discrepancy.

Expected behavior: On iOS and Android there should be consistent behavior and helpful/specific error messages when the following code is run without internet access in the following scenarios:

  • If session/refresh tokens are valid
  • If session token is expired, but refresh token is valid
  • If session/refresh tokens are expired
Amplify.Auth.fetchAuthSession(
  options: CognitoSessionOptions(getAWSCredentials: true),
);

Current Behavior:

  • If session/refresh tokens are valid: Returns CognitoAuthSession on both iOS and Android ✅
  • If session token is expired, but refresh token is valid: Not consistent, not very helpful ❌
    • Android: Returns CognitoAuthSession w/o user sub or tokens immediately after session expiration. Throws SessionExpiredException after ~1 hour after session token expires.
    • iOS: AuthException(message: A network error occured ... )
  • If session/refresh tokens are expired: TBD 🟡

Edit: I was able to reproduce the SessionExpired exception on Android after 1 hour with session token expiration of 5 min and refresh token expiration of 30 days. I have updated the current behavior above.

@Jordan-Nelson Jordan-Nelson added bug Something is not working; the issue has reproducible steps and has been reproduced platform-discrepancy Issues that result in inconsistent behavior between support platforms and removed to-be-reproduced Issues that have not been reproduced yet, but have reproduction steps provided pending-triage This issue is in the backlog of issues to triage labels Mar 15, 2022
@Jordan-Nelson Jordan-Nelson changed the title SessionExpiredException First Offline Mobile Inconsistent behavior when fetching auth session without internet access Mar 15, 2022
@Jordan-Nelson Jordan-Nelson removed their assignment Mar 15, 2022
@Jordan-Nelson Jordan-Nelson changed the title Inconsistent behavior when fetching auth session without internet access Inconsistent/Incorrect behavior when fetching auth session without internet access Mar 15, 2022
@Jordan-Nelson Jordan-Nelson added requires-android-fix This issue is the result of an underlying Amplify Android issue that needs to be fixed. requires-ios-fix This issue is the result of an underlying Amplify iOS issue that needs to be fixed. labels Mar 15, 2022
@miguelflores1993
Copy link
Author

Do you know anything about this functionality?

@vgribok
Copy link

vgribok commented Jun 21, 2022

Once this issue is fixed, what's the longest time an authenticated user can stay offline and rely on the DataStore without getting kicked out: is it determined by the session token max expiration of 36 hours, id/access token max expiration time of 1 day, or is it something else? Can an app for a low-tech fishing boat in Indonesia that stays out in the sea for a week have the authenticated experience longer than 36 hours?

@miguelflores1993
Copy link
Author

Una vez que se solucione este problema, ¿cuál es el tiempo más largo que un usuario autenticado puede permanecer _desconectado _y confiar en DataStore sin ser expulsado ? ¿O es otra cosa? ¿Puede una aplicación para un barco de pesca de baja tecnología en Indonesia que permanece en el mar durante una semana tener la experiencia autenticada por más de 36 horas?

my application works many times offline, that is, international roads or routes without internet, it is an uber of trucks.

Most drivers are offline without internet for up to 3 to 5 days.

@Jordan-Nelson
Copy link
Member

Jordan-Nelson commented Mar 3, 2023

This issue has been addressed in as of v1.0.0-next.4 (developer-preview) of amplify_auth_cognito. Fixing this required making breaking changes to fetchAuthSession.

Prior to the changes, fetchAuthSession would throw an exception if User Pool tokens OR AWS credentials were expired. This led to unexpected behavior since AWS credentials expire after 1 hour while User Pool tokens may be valid for a much longer period.

With the updates, fetchAuthSession will not throw when User Pool tokens or AWS credentials are expired. Instead, the object returned will contain a userPoolTokenResult and a awsCredentialsResult. When accessing the .value getter on these objects, a NetworkException will be thrown if the tokens are expired and cannot be refreshed do to a network error.

@Jordan-Nelson Jordan-Nelson added the fixed-in-release-candidate Issues that have been addressed in the current release-candidate branch label Mar 3, 2023
@Jordan-Nelson
Copy link
Member

This issue has been addressed in v1.0.0 of Amplify Flutter, which is now stable. See #760 (comment) for the changes made related to this issue.

This release also includes web and desktop support for Auth, API, Analytics, and Storage. You can see the list of new features and bug fixes in the release notes, and see more details on how to migrate in the upgrade guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues related to the Auth Category bug Something is not working; the issue has reproducible steps and has been reproduced fixed-in-release-candidate Issues that have been addressed in the current release-candidate branch platform-discrepancy Issues that result in inconsistent behavior between support platforms requires-android-fix This issue is the result of an underlying Amplify Android issue that needs to be fixed. requires-ios-fix This issue is the result of an underlying Amplify iOS issue that needs to be fixed.
Projects
None yet
Development

No branches or pull requests

8 participants