👌

【Flutter】初めてのGoogle認証(Web)

2024/01/11に公開

はじめに

Flutter WebにGoogle認証を初めて実装したので手順をメモとして残すことにしました。
ちなみにiOS/AndroidもGoogle認証を実装してみたのですが、以下の記事を参考にしました。
https://zenn.dev/kazutxt/books/flutter_practice_introduction/viewer/30_chapter4_authentication#googleアカウントによる認証

前提条件

  • FlutterアプリにFirebaseを追加しておく

手順

  • Firebase AuthenticationでGoogle認証を有効にする
  • 必要なPackageをインストールしてGoogle SignIn実装
  • Google Cloud Platformでgoogle-signin-client_idを取得してくる
  • People APIを有効にする

Firebase AuthenticationでGoogle認証を有効にする

FirebaseコンソールでFirebase Authenticationの利用を開始し、Google認証を有効化します。
特に難しいことはないです。以下のスクショの赤枠で囲ったボタン等をタップするなどして進めていくだけです。








必要なPackageをインストールしてGoogle SignIn実装

まず、firebase_authgoogle_sign_inのpackageをインストールします。
firebaseをFlutterに追加した時にfirebase_coreを導入していると思うのでここでは導入済みと思って進めます。firebase_coreをまだインストールしてない場合はpubspec.yamlに記述してflutter pub getでインストールします。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.24.2
  firebase_auth: ^4.16.0
  google_sign_in: ^6.2.1

次に以下のようにmain.dartを修正しました。

main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:sample_flutter_web_google_signin/firebase_options.dart';

Future<void> main() async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const SingInDemo(),
    );
  }
}

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

  
  State<SingInDemo> createState() => _SingInDemoState();
}

class _SingInDemoState extends State<SingInDemo> {
  final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: [
    'email',
  ]);
  GoogleSignInAccount? _currentUser;

  
  void initState() {
    super.initState();
    _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
      setState(() {
        _currentUser = account;
      });
    });
    _googleSignIn.signInSilently();
  }

  Future<void> _handleGoogleSignIn() async {
    try {
      _currentUser = await _googleSignIn.signIn();
    } catch (error) {
      print(error);
    }
  }

  Future<void> _handleGoogleSignOut() async => await _googleSignIn.disconnect();

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Google Signin Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_currentUser != null)
              ListTile(
                leading: GoogleUserCircleAvatar(identity: _currentUser!),
                title: Text(_currentUser?.displayName ?? ''),
                subtitle: Text(_currentUser?.email ?? ''),
              ),
            ElevatedButton(
              onPressed: _handleGoogleSignIn,
              child: const Text('Google SignIn'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: _handleGoogleSignOut,
              child: const Text('Google SignOut'),
            ),
          ],
        ),
      ),
    );
  }
}

ビルドしてサインインを試してみました。すると、以下のようなエラーになります。

"ClientID not set. Either set it on a <meta name=\"google-signin-client_id\" content=\"CLIENT_ID\" /> tag, or pass clientId when initializing GoogleSignIn"

google-signin-client_idというIDをセットしたmetaタグが必要なことがわかりました。
google-signin-client_idはGoogle Cloud Platformで確認ができます。

Google Cloud Platformでgoogle-signin-client_idを取得してくる

  • まずGoogle Cloud Platformでgoogle-signin-client_idを確認しコピーしてきます。

該当のプロジェクトでない場合は変更します。プロジェクト名のリンクをタップし、

以下のダイアログが表示されます。デフォルト状態で該当のプロジェクトが見当たらない場合は「すべて」のタブを選択すると該当のプロジェクトが見つかるので、

該当のプロジェクトを見つけたら選択します。

次に「ダッシュボード」に移動します

APIとサービス > 認証情報 の順に選択して

OAuth2.0クライアントIDのWeb clientのクライアントIDの項目がgoogle-signin-client_idになるのでこれをコピーします。

コピーしたgoogle-signin-client_idをmetaタグのcontentに貼り付け、metaタグはwebディレクトリのindex.html内のheadタグに記述します。

web/index.html
<head>
<meta name="google-signin-client_id"
    content="CLIENT_ID.apps.googleusercontent.com" />
...
</head>

ここまできたらビルドして試してみます。
するとGmailを入力するフォームのポップアップが出てきますので、指示に従って進めます。

パスワード入力を終えたところで以下の画面になりました。

続行を押すと、Macの場合パスキー入力を許可するため指紋認証が出ることがあるので、指示通り指紋認証します。すると、以下のエラーになりました。

[GSI_LOGGER-TOKEN_CLIENT]: The OAuth token was not passed to gapi.client, since the gapi.client library is not loaded in your page.
ClientException: {
  "error": {
    "code": 403,
    "message": "People API has not been used in project 553498935391 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/people.googleapis.com/overview?project=553498935391 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
...

ClientExceptionのmessageを読むとPeople APIが有効になってないということが書かれています。URLが記載されているためこのURLに飛んでPeople APIを有効にする必要がありそうです。

People APIを有効にする

URLのページでは以下のスクショのようになっていますので、有効にするをタップしてAPIを有効にします。

APIを有効にすると以下の画面に切り替わりました。

ここまでで再度ビルドして試してみます。

Google認証してユーザ名やアイコンなどのユーザ情報ができました。

おわりに

今回はFlutter WebでGoogle認証を実装してみました。結構エラーに遭遇しましたがエラーメッセージを読み解いてなんとか実装できました。Flutter WebにGoogle認証を実装してみたい人の参考になれば嬉しいです。

書いたコードはこちら

https://github.com/king-kazu39/SampleFlutterWebGoogleSignIn

Discussion