Flutter谷歌登录重定向插件google_sign_in_web_redirect的使用

Flutter谷歌登录重定向插件google_sign_in_web_redirect的使用

Flutter包实现了谷歌登录重定向(适用于隐身模式)。

集成

首先,参考以下链接创建您的Google Sign-In OAuth客户端ID。

在您的web/index.html文件中,添加以下meta标签,将其放置在文档的head部分:

<meta name="google-signin-client_id" content="YOUR_GOOGLE_SIGN_IN_OAUTH_CLIENT_ID.apps.googleusercontent.com">

为了让客户端正常工作,最后一步是配置授权JavaScript源,这将标识您的应用程序可以从哪些域发送API请求。在本地开发时,这通常是localhost和某个端口。

您可以按照以下步骤进行配置:

  1. 前往凭据页面
  2. 点击您之前创建的OAuth 2.0 Web应用客户端的“编辑”按钮。
  3. 将您想要的URI添加到授权JavaScript源
  4. 添加重定向URI到授权重定向URI

对于本地开发,可以添加一个localhost条目,例如:http://localhost:7357

启动Flutter在http://localhost:7357

通常情况下,flutter run会在一个随机端口启动。在这种需要处理认证的情况下,这种行为可能不太合适。

您可以使用以下命令告诉flutter run监听特定主机和端口的请求:

flutter run -d chrome --web-hostname localhost --web-port 7357

其他API

如果您需要添加其他API(如Google People API),请阅读剩余的说明。

使用

在您的Dart代码中添加以下导入:

void main() {
  GoogleSignWeb.getQueryParameters();///确保添加此行
  setPathUrlStrategy();///此包仅支持PathUrl
  runApp(const MyApp());
}

修复“没有相应的路由”问题与查询参数:

onGenerateRoute: (settings) {
  if (settings.name?.contains("/login") ?? false) {
    return MaterialPageRoute(
      builder: (_) => const LoginScreen(),
    );
  }
  return null;
},

完整的可用范围列表

现在您可以使用GoogleSignWeb类在您的Dart代码中进行身份验证,例如:

initGoogleSignIn() async {
  if(kIsWeb) {
    GoogleSignWeb.init(
      ///id_token如果只想获取用户ID
      ///code如果需要基本资料,访问令牌
      responseType: "code",
      scopes: ['email', 'profile'],
    );
    if(GoogleSignWeb.instance?.queryParameters?.idToken != null) {
      final jwt = await GoogleSignWeb.instance!.verifyToken();
      final userId = jwt.sub;
      Navigator.pushNamed(context, '/main',arguments: userId);
    } else if (GoogleSignWeb.instance?.queryParameters?.code != null) {
      ///TODO 步骤1: 将代码发送到服务器以获取ID令牌及基本资料(姓名、显示名称、图片)
      ///我们不能从客户端创建此API,因为您需要client_secret。
      ///POST /token HTTP/1.1
      ///Host: oauth2.googleapis.com
      ///Content-Type: application/x-www-form-urlencoded
      ///
      ///code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
      ///client_id=your-client-id&
      ///client_secret=your-client-secret&
      ///redirect_uri=https%3A//oauth2.example.com/code&
      ///grant_type=authorization_code
      ///更多详情: https://developers.google.com/identity/protocols/oauth2/openid-connect#exchangecode
      ///
      ///TODO 步骤2: 验证从服务器响应中获得的令牌
      ///
      ///GoogleSignWeb.instance.token = "YOUR_ID_TOKEN_RESPONSE_FROM_SERVER";
      ///GoogleSignWeb.instance.verifyToken();

      try {
        final response = await http.post(Uri.parse("https://six-colts-rhyme-116-110-109-131.loca.lt/auth/idToken"),body: {
          "code":  GoogleSignWeb.instance!.queryParameters!.code,
        },headers: {
          "Access-Control-Allow-Origin": "*"
        });
        final responseData = jsonDecode(response.body);
        GoogleSignWeb.instance!.token = responseData['id_token'];
        ///final accessToken = responseData['access_token'];
        final jwt = await GoogleSignWeb.instance!.verifyToken();
        Navigator.pushNamed(context, '/main',arguments: jwt.name);
      } catch (_) {
        print(_.toString());
      }
    }
  }
}

//按下登录按钮;
GoogleSignWeb.instance?.signIn();

示例

google_sign_in_web_redirect中找到完整的示例。

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in_web_redirect/google_sign_in_web_redirect.dart';
import 'package:url_strategy/url_strategy.dart';
import 'package:http/http.dart' as http;

void main() {
  GoogleSignWeb.getQueryParameters();///确保添加此行
  setPathUrlStrategy();///确保添加此行
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Google SignIn Web Redirect Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      onGenerateRoute: (settings) {///修复“没有相应的路由”问题与查询参数
        if (settings.name?.contains("/login") ?? false) {
          return MaterialPageRoute(
            builder: (_) => const LoginScreen(),
          );
        }
        return null;
      },
      routes: {
        '/welcome': (context) => const WelcomeScreen(),
        '/login': (context) => const LoginScreen(),
        '/main': (context) => const MainScreen(),
      },
      initialRoute: '/welcome',
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  const WelcomeScreen({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("欢迎"),
      ),
      body: Center(
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            primary: Colors.teal,
            onPrimary: Colors.white,
            onSurface: Colors.grey,
          ),
          onPressed: () {
            Navigator.pushNamed(context, '/login');
          },
          child: const Text("前往登录界面"),
        ),
      ),
    );
  }
}

class LoginScreen extends StatefulWidget {
  final SignInGoogleQueryParameters? queryParameters;

  const LoginScreen({Key? key, this.queryParameters}) : super(key: key);

  [@override](/user/override)
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {

  [@override](/user/override)
  void initState() {
    super.initState();
    initGoogleSignIn();
  }

  initGoogleSignIn() async {
    if(kIsWeb) {
      GoogleSignWeb.init(
        ///id_token如果只想获取用户ID
        ///code如果需要基本资料,访问令牌
        responseType: "id_token",
        scopes: ['email', 'profile'],
      );
      if(GoogleSignWeb.instance?.queryParameters?.idToken != null) {
        final jwt = await GoogleSignWeb.instance!.verifyToken();
        final userId = jwt.sub;
        Navigator.pushNamed(context, '/main',arguments: userId);
      } else if (GoogleSignWeb.instance?.queryParameters?.code != null) {
        ///TODO 步骤1: 将代码发送到服务器以获取ID令牌及基本资料(姓名、显示名称、图片)
        ///我们不能从客户端创建此API,因为您需要client_secret。
        ///POST /token HTTP/1.1
        ///Host: oauth2.googleapis.com
        ///Content-Type: application/x-www-form-urlencoded
        ///
        ///code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
        ///client_id=your-client-id&
        ///client_secret=your-client-secret&
        ///redirect_uri=https%3A//oauth2.example.com/code&
        ///grant_type=authorization_code
        ///更多详情: https://developers.google.com/identity/protocols/oauth2/openid-connect#exchangecode
        ///
        ///TODO 步骤2: 验证从服务器响应中获得的令牌
        ///
        ///GoogleSignWeb.instance.token = "YOUR_ID_TOKEN_RESPONSE_FROM_SERVER";
        ///GoogleSignWeb.instance.verifyToken();
        /* try {
          final response = await http.post(Uri.parse("https://six-colts-rhyme-116-110-109-131.loca.lt/auth/idToken"),body: {
            "code":  GoogleSignWeb.instance!.queryParameters!.code,
          },headers: {
            "Access-Control-Allow-Origin": "*"
          });
          final responseData = jsonDecode(response.body);
          GoogleSignWeb.instance!.token = responseData['id_token'];
          ///final accessToken = responseData['access_token'];
          final jwt = await GoogleSignWeb.instance!.verifyToken();
          Navigator.pushNamed(context, '/main',arguments: jwt.name);
        } catch (_) {
          print(_.toString());
        } */
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("登录"),
      ),
      body: Center(
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            primary: Colors.teal,
            onPrimary: Colors.white,
            onSurface: Colors.grey,
          ),
          onPressed: () {
            GoogleSignWeb.instance?.signIn();
          },
          child: const Text("使用Google登录"),
        ),
      ),
    );
  }
}

class MainScreen extends StatelessWidget {
  const MainScreen({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final userId = ModalRoute.of(context)!.settings.arguments as String? ?? "";
    return Scaffold(
      appBar: AppBar(
        title: const Text("登录"),
      ),
      body: Text("你好 $userId"),
    );
  }
}

更多关于Flutter谷歌登录重定向插件google_sign_in_web_redirect的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter谷歌登录重定向插件google_sign_in_web_redirect的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于google_sign_in_web_redirect插件在Flutter中的使用,这里是一个具体的代码示例,展示如何集成并实现谷歌登录功能。这个插件主要用于在Web平台上进行谷歌登录,通过重定向的方式处理OAuth认证流程。

首先,确保你的Flutter项目已经添加了对google_sign_ingoogle_sign_in_web_redirect的依赖。在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  google_sign_in: ^5.0.0  # 请检查最新版本
  google_sign_in_web_redirect: ^0.4.0  # 请检查最新版本

然后运行flutter pub get来安装这些依赖。

接下来,在你的Flutter项目中,按照以下步骤配置和实现谷歌登录:

  1. 配置Google Cloud Platform项目

    • 创建一个新的GCP项目或在现有项目中配置OAuth 2.0客户端ID。
    • 在“凭据”部分,创建一个Web应用凭据,获取客户端ID和客户端密钥。
    • 将重定向URI设置为你的Flutter Web应用的URL,例如https://your-flutter-app.web.app/login
  2. 在Flutter应用中配置

    • web/index.html文件中,添加Google Sign-In所需的JavaScript库:

      <head>
        <script src="https://accounts.google.com/gsi/client" async defer></script>
      </head>
      
  3. 实现登录逻辑

    import 'package:flutter/material.dart';
    import 'package:google_sign_in/google_sign_in.dart';
    import 'package:google_sign_in_web_redirect/google_sign_in_web_redirect.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Google Sign In Example'),
            ),
            body: Center(
              child: GoogleSignInButton(
                onPressed: () async {
                  // Ensure the web redirect plugin is registered
                  GoogleSignInWebRedirect.register();
    
                  final GoogleSignIn _googleSignIn = GoogleSignIn(
                    clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
                    scopes: [
                      'email',
                      'https://www.googleapis.com/auth/userinfo.profile',
                    ],
                  );
    
                  final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
    
                  if (googleUser == null) return;
    
                  final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    
                  // Here you can use the `googleAuth.accessToken` to access Google APIs
                  print('Access Token: ${googleAuth.accessToken}');
    
                  // Optionally, you can also get the user's profile information
                  final GoogleSignInAccount googleUserProfile = await googleUser;
                  print('User ID: ${googleUserProfile.id}');
                  print('Email: ${googleUserProfile.email}');
                  print('Display Name: ${googleUserProfile.displayName}');
                },
              ),
            ),
          ),
        );
      }
    }
    
    class GoogleSignInButton extends StatelessWidget {
      final VoidCallback onPressed;
    
      GoogleSignInButton({required this.onPressed});
    
      @override
      Widget build(BuildContext context) {
        return ElevatedButton(
          onPressed: onPressed,
          child: Text('Sign in with Google'),
          style: ElevatedButton.styleFrom(
            primary: Colors.blue,
            textStyle: TextStyle(color: Colors.white),
          ),
        );
      }
    }
    

在上面的代码中,请确保将YOUR_CLIENT_ID.apps.googleusercontent.com替换为你从Google Cloud Platform获取的客户端ID。

这个示例展示了如何配置和使用google_sign_in_web_redirect插件在Flutter Web应用中进行谷歌登录。用户点击按钮后,将通过重定向流程进行OAuth认证,认证成功后,你可以获取用户的访问令牌和基本信息。

回到顶部