Flutter Google Sign-In 与 google_sign_in 7:了解新的身份验证流程
Source: Dev.to
google_sign_in ^7.0.0 中的变化
从 google_sign_in ^7.0.0 开始,插件进行了一次重大重构,以支持 Android Credential Manager 和现代 Google Identity Services。这带来了若干破坏性更改,摆脱了传统的“一站式” signIn() 方法。如果你最近升级了 Flutter 项目,可能会遇到编译错误或意外行为,例如:
GoogleSignIn()构造函数不再存在signIn()方法被移除GoogleSignInAuthentication中缺少accessToken- 除非调用
initialize(),否则不会出现账户选择器
这些变化源于一种架构转变:认证(authentication)和授权(authorization)现在被分开处理。
修复 1 — 移除 GoogleSignIn 构造函数(单例模式)
GoogleSignIn 类不再允许使用 GoogleSignIn() 直接实例化。
请改用单例实例:
final googleSignIn = GoogleSignIn.instance;
修复 2 — 初始化现在是强制性的
在使用插件之前必须仅执行一次初始化。可在应用启动时调用(例如在 main() 或你的认证服务初始化时):
await GoogleSignIn.instance.initialize();
跳过此步骤可能导致认证弹窗不出现。
修复 3 — signIn() 被 authenticate() 取代
旧的 signIn() 方法已被 authenticate() 替代,它会在受支持的 Android 版本上触发新的系统级账户选择器 / Credential Manager 弹窗:
final GoogleSignInAccount googleUser =
await GoogleSignIn.instance.authenticate();
修复 4 — accessToken 缺失(认证 vs. 授权)
Google 将 认证(用户身份)与 授权(应用拥有的权限)分离。调用 authenticate() 后,你可以通过 googleUser.authentication 获取 idToken,但 accessToken 不再自动返回。需要显式请求所需的作用域:
final clientAuth = await googleUser.authorizationClient
.authorizeScopes(['email', 'profile']);
示例:使用 Google 和 Firebase 登录
如果你需要同时获取两个令牌(例如用于 Firebase),可以使用以下模式:
Future signInWithGoogle() async {
// 1. 确保初始化
final googleSignIn = GoogleSignIn.instance;
await googleSignIn.initialize();
// 2. 认证(身份)
final GoogleSignInAccount googleUser =
await googleSignIn.authenticate();
// 3. 授权(权限)
final List scopes = ['email', 'profile'];
final clientAuth =
await googleUser.authorizationClient.authorizeScopes(scopes);
// 4. 创建 Firebase 凭证
final credential = GoogleAuthProvider.credential(
idToken: googleUser.authentication.idToken,
accessToken: clientAuth.accessToken,
);
// 5. 使用 Firebase 登录
return await FirebaseAuth.instance.signInWithCredential(credential);
}
重要提示: 在调用
signInWithGoogle()之前,请在应用启动时调用一次GoogleSignIn.instance.initialize()。
结语
新的 google_sign_in API 起初可能会让人感到困惑,因为许多熟悉的方法被移除或重新设计。理解认证与授权的分离有助于理清新流程,并使插件与现代身份系统保持一致。希望本指南能为你节省调试时间。