amplify-flutter
amplify-flutter copied to clipboard
Inconsistent/Incorrect behavior when fetching auth session without internet access
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));
@flutteresbolivia Is this on Android or iOS? And is the refresh token actually valid?
@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.
@flutteresbolivia What is the expected behavior, exactly? A network exception?
@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.
@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?
Hi @flutteresbolivia
Following up on this. If you are still experiencing an issue, please provide the info requested above.
Regards Mo
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
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.
I have the same issue, even if I do Amplify.Auth.signOut(), the next time the exception is always SessionExpiredException instead of SignedOutException.
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
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?
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>
@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.
@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:- I do SignIn
- fetchAuthSession to check that is works, and it does work
- close the app
- wait 6min (on cognito I have set ID token and Access token expiration = 5min)
- turn internet off
- launch the app
- 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
- the access token is expired
- amplify tries to use the refresh token to get a new valid access token
- 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.
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
- I do SignIn
- fetchAuthSession to check that it works, and it does work
- close the app
- wait 6min (on cognito I have set ID token and Access token expiration = 5min)
- turn internet off
- launch the app
- fetchAuthSession -> OK but with null tokens
- Wait longer (I have waited like 1h30m)
- launch the app
- 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):
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.
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
@gianmarcocalbi - Okay, I am not sure what would be different between 5+ minutes and 1 hour. I'll see if I can reproduce this.
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.
Do you know anything about this functionality?
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?
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.
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.
This issue has been addressed in v1.0.0 of Amplify Flutter, which is now stable. See https://github.com/aws-amplify/amplify-flutter/issues/760#issuecomment-1453559459 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.