Google Sign In中serverAuthCode返回null问题求助
解决Google登录serverAuthCode返回null的问题
问题重现
应用日志
D/EGL_emulation( 9260): app_time_stats: avg=83219.91ms min=1.44ms max=2329685.50ms count=28 W/Auth ( 9260): [GoogleAuthUtil] isUserRecoverableError status: NEED_REMOTE_CONSENT I/flutter ( 9260): Google Access Token: ya29.a0AfB_byBhIKqNK1teL9pzZNxgktKDnX2KhStaxB8X1pmxS0EPGphifjZdmXFHMW5R5-j70PRE-2sYmPIr1EttYQTBsibG89ZGzjOq2b_Nal3G5n3P3QpFI2YAERNnsozvh1Vh0A-BuPuQDAnGeRzY4FFzrzs-gAgeJAaCgYKASMSARASFQHGX2MibSgPlsx9vVc3vLiAkYNKsQ0169 I/flutter ( 9260): Google Server Auth Code: I/flutter ( 9260): Google Id Token: I/flutter ( 9260): Google Email: nurain.cubosquare@gmail.com I/flutter ( 9260): Google Id : 113699528046273182780
实现代码
// Add these imports at the top of your file import 'package:flutter/material.dart'; import 'package:google_sign_in/google_sign_in.dart'; class GoogleSignInApi { static final _googleSignIn = GoogleSignIn(scopes: [ 'email', 'https://www.googleapis.com/auth/userinfo.profile', ]); static Future<GoogleSignInAccount?> signIn() => _googleSignIn.signIn(); } class YourWidget extends StatefulWidget { @override _YourWidgetState createState() => _YourWidgetState(); } class _YourWidgetState extends State<YourWidget> { String googleEmail = ''; String googleId = ''; String googlePhotoUrl = ''; String googleServerAuthCode = ''; String googleAccessToken = ''; String googleIdToken = ''; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: () { _handleSignIn(); }, child: Text('Sign In with Google'), ), ), ); } void _handleSignIn() { GoogleSignInApi.signIn().then((userData) { if (userData != null) { userData.authentication.then((googleKey) { setState(() { // Retrieve the data from Google auth googleEmail = userData.email; googleId = userData.id; // googlePhotoUrl = userData.photoUrl; googleServerAuthCode = userData.serverAuthCode ?? ''; googleAccessToken = googleKey.accessToken ?? ''; googleIdToken = googleKey.idToken ?? ''; }); print("Google Access Token: $googleAccessToken"); print("Google Server Auth Code: $googleServerAuthCode"); print("Google Id Token: $googleIdToken"); print("Google Email: $googleEmail"); print("Google Id : $googleId"); // Call your login function if no errors checkInternetAndLoginWithGoogle(); }).catchError((err) { print('Inner error: $err'); }); } else { print('User cancelled sign in'); } }).catchError((err) { print('Error occurred: $err'); }); } void checkInternetAndLoginWithGoogle() { // Implement your login logic here // This method will be called after successfully retrieving Google user data } }
解决方法
1. 配置Web客户端ID(核心步骤)
serverAuthCode仅在初始化GoogleSignIn时指定Web类型客户端ID后才会返回,这是当前代码的核心缺失项:
- 登录Google Cloud控制台,找到你的OAuth 2.0客户端ID,选择Web应用类型的ID(不要用Android/iOS客户端ID)。
- 修改
GoogleSignInApi初始化代码:
class GoogleSignInApi { static final _googleSignIn = GoogleSignIn( scopes: [ 'email', 'https://www.googleapis.com/auth/userinfo.profile', ], // 替换为你的Web客户端ID clientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com', ); static Future<GoogleSignInAccount?> signIn() => _googleSignIn.signIn(); }
2. 处理NEED_REMOTE_CONSENT警告
该警告表示用户需要重新授权,可通过「先静默登录、失败再触发显式授权」的流程优化:
void _handleSignIn() { GoogleSignInApi._googleSignIn.signInSilently().then((userData) { if (userData != null) { _fetchAuthData(userData); } else { GoogleSignInApi.signIn().then((userData) { if (userData != null) { _fetchAuthData(userData); } else { print('User cancelled sign in'); } }).catchError((err) { print('Error occurred: $err'); }); } }).catchError((err) { print('Silent sign in failed: $err'); GoogleSignInApi.signIn().then((userData) { if (userData != null) { _fetchAuthData(userData); } }); }); } // 提取授权数据获取逻辑到单独方法 void _fetchAuthData(GoogleSignInAccount userData) { userData.authentication.then((googleKey) { setState(() { googleEmail = userData.email; googleId = userData.id; googleServerAuthCode = userData.serverAuthCode ?? ''; googleAccessToken = googleKey.accessToken ?? ''; googleIdToken = googleKey.idToken ?? ''; }); print("Google Access Token: $googleAccessToken"); print("Google Server Auth Code: $googleServerAuthCode"); print("Google Id Token: $googleIdToken"); print("Google Email: $googleEmail"); print("Google Id : $googleId"); checkInternetAndLoginWithGoogle(); }).catchError((err) { print('Inner error: $err'); }); }
3. 验证OAuth同意屏幕配置
- 确保Google Cloud控制台的OAuth同意屏幕已发布(针对外部用户),添加的权限范围已完成审核。
- 测试时使用已添加到测试用户列表的账号,避免权限未发布导致的授权异常。
内容的提问来源于stack exchange,提问作者Raza Mehdi
相关产品推荐
相关产品推荐

