AWS Amplify for Flutter:已提示登录却无法获取当前用户的冲突问题
问题根因
- Amplify Auth维护了两层校验逻辑:本地持久化缓存的登录状态标记、服务端实际有效session状态。你遇到的冲突是两层校验不同步导致的:本地残留了旧用户的登录标记,调用
signIn时触发本地校验抛出「已存在登录用户」异常;但该标记对应的session实际已过期,调用getCurrentUser时校验session有效性失败,返回已登出提示。 - 原有代码存在逻辑漏洞:调用
signOut时未强制清空本地所有缓存状态,且未确认状态完全清理完成就执行后续登录操作,容易残留无效状态。
修复步骤
1. 强制清理本地Auth缓存
调用signOut时传入全局登出配置,强制清空本地所有残留的Auth状态,避免状态不同步:
await Amplify.Auth.signOut(options: const SignOutOptions(globalSignOut: true));
2. 增加InvalidStateException异常的兼容逻辑
调用signIn时如果遇到该异常,先强制清理缓存,再重试一次登录操作。
3. 完整修改后的代码
signIn(String password, void Function(String, String) onSuccess, Future<void> Function(String) onFailure) async { AuthUser? currentUser; _isSignIn = false; try { currentUser = await Amplify.Auth.getCurrentUser(); if (currentUser.username == _username) { _isSignIn = true; } else { // 强制全局登出,清空所有本地缓存 await Amplify.Auth.signOut(options: const SignOutOptions(globalSignOut: true)); // 增加短延迟等待状态同步,可适配低性能设备 await Future.delayed(const Duration(milliseconds: 200)); } } on Exception catch (e) { _isSignIn = false; // 无有效登录用户时也尝试清一次缓存,避免残留无效标记 try { await Amplify.Auth.signOut(options: const SignOutOptions(globalSignOut: true)); } catch (_) {} } try { SignInResult res; if (!_isSignIn) { try { res = await Amplify.Auth.signIn( username: _username, password: password, ); } on InvalidStateException catch (_) { // 遇到状态异常先清缓存重试一次 await Amplify.Auth.signOut(options: const SignOutOptions(globalSignOut: true)); await Future.delayed(const Duration(milliseconds: 200)); res = await Amplify.Auth.signIn( username: _username, password: password, ); } if (res.isSignedIn) { _isSignIn = res.isSignedIn; currentUser = await Amplify.Auth.getCurrentUser(); } } if (_isSignIn && currentUser != null) { List<AuthUserAttribute> attributes = await Amplify.Auth.fetchUserAttributes(); onSuccess( currentUser.userId, attributes .firstWhere( (attribute) => attribute.userAttributeKey == 'email') .value); _isEmailVerified = attributes .firstWhere((attribute) => attribute.userAttributeKey == 'email_verified') .value == 'true'; } } on NotAuthorizedException catch (notAuthorizedException) { await onFailure(notAuthorizedException.message); } on AuthException catch (e) { print(e); try { await Amplify.Auth.getCurrentUser(); } catch (_) {} await onFailure(e.message); } }
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

