Flutter中使用Amplify Auth获取JWT/访问令牌及Identity ID失败的问题求助
Flutter中使用Amplify Auth获取JWT/访问令牌及Identity ID失败的问题求助
问题描述
看起来你遇到的问题是:使用Amplify Auth Cognito的WebUI登录成功后,虽然isSignedIn返回true,且能看到userPoolTokens包含访问令牌,但调用fetchCognitoAuthSession()时却报错Error retrieving auth session: The AWS credentials could not be retrieved.,无法正常获取Identity ID和JWT令牌。
先贴出你的原始代码方便分析:
import 'dart:async'; import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; import '../amplifyconfiguration.dart'; import 'package:amplify_flutter/amplify_flutter.dart'; class LogInService { LogInService() { _configureAmplify(); } Future<void> _configureAmplify() async { try { AmplifyAuthCognito auth = AmplifyAuthCognito(); await Amplify.addPlugin(auth); await Amplify.configure(amplifyconfig); } on Exception catch (e) { safePrint('An error occurred configuring Amplify: $e'); } } Future<bool> signInWithWebUI() async { try { final result = await Amplify.Auth.signInWithWebUI(); final creds = await Amplify.Auth.fetchAuthSession(); safePrint('Sign in result: $creds'); if (creds.isSignedIn) { fetchCognitoAuthSession(); return true; } else { return false; } } on AuthException catch (e) { safePrint('Error signing in: ${e.message}'); return false; } } Future<void> fetchCognitoAuthSession() async { try { final cognitoPlugin = Amplify.Auth.getPlugin(AmplifyAuthCognito.pluginKey); final result = await cognitoPlugin.fetchAuthSession(); final accessToken = result. // 这里存在未完成的语法错误 final identityId = result.identityIdResult.value; safePrint("Current user's identity ID: $identityId"); } on AuthException catch (e) { safePrint('Error retrieving auth session: ${e.message}'); } } Future<void> signOutWithWebUI() async { try { await Amplify.Auth.signOut(); safePrint("Signed out successfully"); } on AuthException catch (e) { safePrint(e.message); } } }
问题分析
我梳理了几个可能导致问题的关键点:
- 语法错误阻塞逻辑:
fetchCognitoAuthSession()里final accessToken = result.这行代码未完成,会直接导致编译/运行错误,影响后续的Identity ID获取逻辑。 - Identity ID的获取前提:要拿到Identity ID,必须确保Cognito身份池和用户池已正确关联,且身份池的认证角色拥有
sts:GetFederationToken等必要权限,否则无法生成身份凭证。 - 会话获取方式不当:直接通过插件实例调用
fetchAuthSession()的方式不够稳妥,建议通过通用的Amplify.Auth.fetchAuthSession()获取会话后,再转换为Cognito特定会话处理。 - JWT令牌的获取位置:其实登录成功后,JWT令牌(idToken/accessToken)已经包含在
userPoolTokens中,无需单独通过插件会话重复获取。
解决办法
下面是修改后的完整代码,包含正确的令牌和Identity ID获取逻辑:
import 'dart:async'; import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; import '../amplifyconfiguration.dart'; import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_auth_cognito/src/cognito_auth_session.dart'; class LogInService { LogInService() { _configureAmplify(); } Future<void> _configureAmplify() async { try { AmplifyAuthCognito auth = AmplifyAuthCognito(); await Amplify.addPlugin(auth); await Amplify.configure(amplifyconfig); } on Exception catch (e) { safePrint('An error occurred configuring Amplify: $e'); } } Future<bool> signInWithWebUI() async { try { await Amplify.Auth.signInWithWebUI(); // 登录成功后直接拉取完整认证信息 await fetchAuthDetails(); return true; } on AuthException catch (e) { safePrint('Error signing in: ${e.message}'); return false; } } Future<void> fetchAuthDetails() async { try { // 强制刷新会话,确保拿到最新的认证信息 final authSession = await Amplify.Auth.fetchAuthSession( options: const FetchAuthSessionOptions(forceRefresh: true), ); if (authSession.isSignedIn && authSession is CognitoAuthSession) { // 获取JWT令牌(idToken用于后端API认证,accessToken用于Cognito操作) final tokenResult = authSession.userPoolTokensResult; if (tokenResult.isSuccess) { final tokens = tokenResult.value; safePrint('Access Token (JWT): ${tokens.accessToken}'); safePrint('ID Token (JWT): ${tokens.idToken}'); } // 获取Identity ID final identityResult = authSession.identityIdResult; if (identityResult.isSuccess) { safePrint("Current user's identity ID: ${identityResult.value}"); } else { safePrint('Failed to get Identity ID: ${identityResult.error?.message}'); } // 获取AWS凭证(如果需要调用S3、AppSync等其他AWS服务) final credResult = authSession.awsCredentialsResult; if (credResult.isSuccess) { safePrint('AWS Access Key: ${credResult.value.accessKeyId}'); } else { safePrint('Failed to get AWS credentials: ${credResult.error?.message}'); } } else { safePrint('User is not signed in'); } } on AuthException catch (e) { safePrint('Error retrieving auth details: ${e.message}'); } } Future<void> signOutWithWebUI() async { try { await Amplify.Auth.signOut( options: const SignOutOptions(globalSignOut: true), // 可选:全局登出所有设备 ); safePrint("Signed out successfully"); } on AuthException catch (e) { safePrint(e.message); } } }
额外注意事项
- 身份池配置检查:确保Cognito身份池已和用户池建立信任关系,且认证角色的IAM策略允许
cognito-identity:GetId、sts:GetFederationToken等操作。 - 令牌使用场景:
idToken:用于你的后端API认证,后端可以通过Cognito公钥验证JWT的合法性accessToken:主要用于Cognito用户池的操作(比如获取用户信息)
- 配置文件验证:检查
amplifyconfiguration.dart中是否包含正确的身份池ID、用户池ID等配置项。
备注:内容来源于stack exchange,提问作者antonhs
相关产品推荐
相关产品推荐

