Flutter如何对接google_sign_in与Cognito实现无WebView谷歌登录
Flutter 对接 Cognito + google_sign_in 实现无WebView谷歌登录
前置配置
- 先在AWS Cognito用户池的「身份提供商」菜单中添加Google联邦登录,填入Google Cloud控制台申请的OAuth2客户端ID、密钥,授权回调地址配置应用自定义Scheme(例如
yourapp://auth),不要配置Web端回调地址。 - Google Cloud控制台中,对应OAuth客户端需要分别配置Android端的包名、签名SHA1值,iOS端的Bundle ID,授权重定向URI和Cognito侧填写的回调地址保持完全一致。
- Flutter项目pubspec.yaml中添加两个核心依赖:
amazon_cognito_identity_dart_2(处理Cognito鉴权逻辑)、google_sign_in(调用系统原生谷歌登录能力),不要引入依赖内嵌WebView的Cognito UI类插件。
对接实现步骤
- 端侧触发原生谷歌登录,直接调用设备谷歌服务的授权弹窗,全程不加载Web页面,拿到谷歌返回的身份凭证:
import 'package:google_sign_in/google_sign_in.dart'; // 初始化谷歌登录实例,申请必要的权限scope final GoogleSignIn _googleSignIn = GoogleSignIn( scopes: ['openid', 'email', 'profile'], ); Future<String?> _fetchGoogleIdToken() async { final GoogleSignInAccount? account = await _googleSignIn.signIn(); if (account == null) return null; // 用户取消登录 final GoogleSignInAuthentication auth = await account.authentication; return auth.idToken; // 必须拿idToken,传accessToken会被Cognito拒绝 }
- 将拿到的谷歌idToken传给Cognito服务端,通过联邦登录接口兑换Cognito自身的会话凭证:
import 'package:amazon_cognito_identity_dart_2/cognito.dart'; // 初始化Cognito用户池实例 final _userPool = CognitoUserPool( '你的Cognito用户池ID', '你的Cognito应用客户端ID', ); Future<CognitoUserSession?> _loginToCognitoWithGoogle(String googleIdToken) async { return await _userPool.federatedLogin( 'Google', AuthenticationDetails(authParameters: {'token': googleIdToken}), ); }
- 拿到CognitoUserSession之后,后续接口鉴权、用户属性读取、token刷新逻辑和普通账号密码登录的处理逻辑完全一致,不需要额外适配。
无WebView方案说明
- 上述流程本身就是完全不依赖WebView的实现方案,核心是跳过Cognito默认的托管登录页(该页面默认在WebView中加载,会触发WebView相关的兼容问题),端侧直接调用原生谷歌SDK完成授权,再通过Cognito后端接口完成token交换,全程只有系统原生弹窗,无任何Web页面加载。
- 常见踩坑点:
- Cognito的移动端应用客户端不要开启「客户端密钥」选项,移动端属于公开客户端,开启后联邦登录接口会直接报参数校验错误。
- 不要使用
flutter_web_auth这类靠拉起应用内WebView加载Cognito登录页的方案,这类方案不仅依赖WebView,在iOS上还会触发系统权限提示,部分无GMS的安卓设备上会直接登录失败。 - 传给Cognito的必须是谷歌返回的
idToken,不能传accessToken,Cognito需要校验idToken内的签名和用户身份字段。
内容的提问来源于stack exchange,提问作者Deyaa AL Pozan
相关产品推荐
相关产品推荐

