You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter跨平台应用接入Google APIs的OAuth 2.0认证实现求助

Flutter跨平台(Web/Android/iOS)Google OAuth 2.0 最简实现

依赖安装

先在项目的pubspec.yaml中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  google_sign_in: ^6.2.1
  googleapis: ^12.0.0

执行安装命令:

flutter pub get

平台配置要点

  • Android:将Google Cloud Console下载的google-services.json放在android/app目录下,确保Cloud Console已注册你的应用SHA-1指纹。
  • iOS:将GoogleService-Info.plist放在ios/Runner目录下,在Info.plist中添加URL Scheme(格式为com.googleusercontent.apps.你的客户端ID)。
  • Web:在web/index.html的<head>标签内加入:
<script src="https://accounts.google.com/gsi/client" async defer></script>

同时在Cloud Console配置Web应用的授权回调URL(本地调试用http://localhost:5000,生产环境填你的域名)。

可直接复用的认证+API调用代码

下面是完整的可运行示例,包含登录UI、用户信息展示和Google Drive API调用:

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:googleapis/drive/v3.dart' as drive;
import 'package:http/http.dart' as http;

class GoogleOAuthDemo extends StatefulWidget {
  const GoogleOAuthDemo({super.key});

  @override
  State<GoogleOAuthDemo> createState() => _GoogleOAuthDemoState();
}

class _GoogleOAuthDemoState extends State<GoogleOAuthDemo> {
  GoogleSignInAccount? _currentUser;
  // 初始化Google登录实例,这里添加需要的API权限范围
  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: [
      'email',
      'https://www.googleapis.com/auth/drive.readonly', // 示例用Drive只读权限,按需修改
    ],
  );

  @override
  void initState() {
    super.initState();
    // 监听用户登录状态变化
    _googleSignIn.onCurrentUserChanged.listen((account) {
      setState(() {
        _currentUser = account;
      });
    });
    // 尝试静默登录(记住上次登录状态)
    _googleSignIn.signInSilently();
  }

  // 处理登录逻辑
  Future<void> _handleSignIn() async {
    try {
      await _googleSignIn.signIn();
      // 登录成功后自动调用一次API示例
      await _fetchDriveFiles();
    } catch (error) {
      print('登录失败: $error');
    }
  }

  // 处理退出登录
  Future<void> _handleSignOut() async {
    _googleSignIn.disconnect();
  }

  // 调用Google Drive API示例
  Future<void> _fetchDriveFiles() async {
    if (_currentUser == null) return;
    // 获取认证头
    final authHeaders = await _currentUser!.authHeaders;
    final client = http.Client();
    // 包装带认证的客户端
    final authenticatedClient = GoogleAuthClient(client, authHeaders);
    final driveApi = drive.DriveApi(authenticatedClient);
    
    try {
      // 获取5个Drive文件
      final files = await driveApi.files.list(pageSize: 5);
      print('Drive文件列表: ${files.files?.map((f) => f.name)}');
      // 弹出提示
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('已获取5个Drive文件,详情查看控制台')),
      );
    } catch (error) {
      print('调用API失败: $error');
    } finally {
      client.close();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Google OAuth Demo')),
      body: Center(
        child: _currentUser == null
            // 未登录时显示登录按钮
            ? ElevatedButton(
                onPressed: _handleSignIn,
                child: const Text('使用Google登录'),
              )
            // 已登录时显示用户信息和操作按钮
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('当前用户: ${_currentUser!.displayName}'),
                  Text('邮箱: ${_currentUser!.email}'),
                  const SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: _handleSignOut,
                    child: const Text('退出登录'),
                  ),
                  const SizedBox(height: 10),
                  ElevatedButton(
                    onPressed: _fetchDriveFiles,
                    child: const Text('调用Drive API'),
                  ),
                ],
              ),
      ),
    );
  }
}

// 自定义HTTP客户端,用于给Google API请求添加认证头
class GoogleAuthClient extends http.BaseClient {
  final http.Client _client;
  final Map<String, String> _headers;

  GoogleAuthClient(this._client, this._headers);

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers.addAll(_headers);
    return _client.send(request);
  }
}

使用说明

把上述GoogleOAuthDemo作为你的Flutter应用的主页面(或导航到该页面),运行后即可看到完整的登录流程,登录成功后可调用Google Drive API获取文件列表。

内容的提问来源于stack exchange,提问作者Thomas Fischer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 16:05:05