Flutter 接入 Google Sign In(不用Firebase)
Flutter 接入 Google Sign in
创建 OAuth Client
1. 前往 Google Cloud Console
2. 创建一个新项目

3. 去侧边栏找到 OAuth Consent Screen

4. 进入 OAuth Consent Screen 后,在侧边栏找到 Client

5. 分别创建 iOS 和 Android 的 client
- 
iOS

- 
Android

6. 创建好后下载对应的plist(iOS)和 json(Android)文件


7. 将下载好的文件分别放到项目中(Android)

项目配置
1. 在Flutter依赖中添加依赖(pubspec.yaml)

2. 在 iOS 的 info.plist 文件中添加
<!-- Google Sign-in Section -->
<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleTypeRole</key>
		<string>Editor</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<!-- REVERSED_CLIENT_ID -->
			<string>你下载下来的 plist 文件中的 REVERSED_CLIENT_ID</string>
		</array>
	</dict>
</array>
<key>GIDClientID</key>
<string>你下载下来的 plist 文件中的 ClientId</string>
编写登录代码
下面是一个简单的工具类示例
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
class GoogleAuthService {
  static final GoogleAuthService _instance = GoogleAuthService._internal();
  factory GoogleAuthService() => _instance;
  GoogleAuthService._internal();
  final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email', 'profile']);
  GoogleSignInAccount? _currentUser;
  bool _isSignedIn = false;
  GoogleSignInAccount? get currentUser => _currentUser;
  bool get isSignedIn => _isSignedIn;
  // 初始化服务
  Future<void> initialize() async {
    _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
      _currentUser = account;
      _isSignedIn = account != null;
      _saveUserToPrefs();
    });
    // 检查是否已经登录
    _currentUser = await _googleSignIn.signInSilently();
    _isSignedIn = _currentUser != null;
  }
  // 登录
  Future<GoogleSignInAccount?> signIn() async {
    try {
      final GoogleSignInAccount? account = await _googleSignIn.signIn();
      if (account != null) {
        _currentUser = account;
        _isSignedIn = true;
        await _saveUserToPrefs();
        return account;
      }
      return null;
    } catch (error) {
      debugPrint('Google Sign-In Error: $error');
      return null;
    }
  }
  // 登出
  Future<void> signOut() async {
    try {
      await _googleSignIn.signOut();
      _currentUser = null;
      _isSignedIn = false;
      await _clearUserFromPrefs();
    } catch (error) {
      debugPrint('Google Sign-Out Error: $error');
    }
  }
  // 获取用户详细信息
  Future<Map<String, dynamic>?> getUserInfo() async {
    if (_currentUser == null) return null;
    try {
      final GoogleSignInAuthentication auth =
          await _currentUser!.authentication;
      // 获取用户基本信息
      final userInfo = {
        'id': _currentUser!.id,
        'email': _currentUser!.email,
        'displayName': _currentUser!.displayName,
        'photoUrl': _currentUser!.photoUrl,
        'serverAuthCode': auth.serverAuthCode,
        'accessToken': auth.accessToken,
        'idToken': auth.idToken,
      };
      // 如果服务器授权码存在,可以用于后端验证
      if (auth.serverAuthCode != null) {
        // 这里可以调用你的后端API来验证token
        // await _verifyTokenWithBackend(auth.serverAuthCode!);
      }
      return userInfo;
    } catch (error) {
      debugPrint('Get User Info Error: $error');
      return null;
    }
  }
  // 保存用户信息到本地存储
  Future<void> _saveUserToPrefs() async {
    if (_currentUser == null) return;
    final prefs = await SharedPreferences.getInstance();
    final userData = {
      'id': _currentUser!.id,
      'email': _currentUser!.email,
      'displayName': _currentUser!.displayName,
      'photoUrl': _currentUser!.photoUrl,
    };
    await prefs.setString('google_user_data', jsonEncode(userData));
    await prefs.setBool('is_signed_in', true);
  }
  // 从本地存储清除用户信息
  Future<void> _clearUserFromPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('google_user_data');
    await prefs.setBool('is_signed_in', false);
  }
  // 从本地存储加载用户信息
  Future<void> loadUserFromPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    final isSignedIn = prefs.getBool('is_signed_in') ?? false;
    if (isSignedIn) {
      final userDataString = prefs.getString('google_user_data');
      if (userDataString != null) {
        try {
          final userData = jsonDecode(userDataString) as Map<String, dynamic>;
          // 注意:这里只是恢复基本信息,完整的GoogleSignInAccount对象需要重新登录
          _isSignedIn = true;
        } catch (e) {
          debugPrint('Error parsing user data: $e');
          await _clearUserFromPrefs();
        }
      }
    }
  }
  // 验证token与后端(可选)
  Future<bool> _verifyTokenWithBackend(String serverAuthCode) async {
    try {
      // 这里应该调用你的后端API来验证Google token
      // final response = await http.post(
      //   Uri.parse('YOUR_BACKEND_URL/verify-google-token'),
      //   body: {'serverAuthCode': serverAuthCode},
      // );
      // return response.statusCode == 200;
      return true; // 暂时返回true
    } catch (error) {
      debugPrint('Backend verification error: $error');
      return false;
    }
  }
}
大功告成!
参考:
Flutter Tutorial - Google SignIn WITHOUT Firebase
google_sign_in

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号