hoony's web study

728x90
반응형

1. Google Cloud 에 프로젝트와 인증 절차 설정

https://console.cloud.google.com/

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

 

프로젝트 생성 후, 해당 프로젝트를 선택해줍니다.

OAuth 동의 화면을 생성해줍니다.

사용자 인증 정보중 OAuth 클라이언트 ID를 세팅해주도록 합니다. 본문에서는 안드로이드를 다루기때문

안드로이드 클라이언트로 생성해줍니다.

Hash Key 값 등록을 위해, 아래 절차를 따르도록 합니다.

OS가 Windows 인 경우, OpenSSL을 별도로 설치해야합니다. OpenSSL의 버전에 따른 Hash Key값이 상이한

이슈가 있으므로, openssl-0.9.8e_X64 를 다운받도록 합니다.

[OpenSSL 다운로드 홈페이지]
[OpenSSL 0.9.8.e_X64 다운]

#Debug Key 구하기

[Mac]

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64

[Window]

keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64

 

위의 과정을 모두 마쳤다면, keystore 를 생성 후 프로젝트에 만들어주도록 합니다.

https://docs.flutter.dev/deployment/android#create-an-upload-keystore

#KeyStore Upload

[Mac/Linux]

  keytool -genkey -v -keystore ~/googlelogindebug-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias androiddebugkey

 

  keytool -genkey -v -keystore %userprofile%\googlelogindebug-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias androiddebugkey

 

해당 key store 파일을 Flutter 프로젝트의 /android/app/ 경로에 위치 시켜주도록 합니다.

이후, build.gradle 에 해당 키파일을 설정해주도록 합니다.

[build.gradle - app]

/*
 구글 로그인 관련 키파일 설정
* */
signingConfigs {
    debug {
        keyAlias 'androiddebugkey'
        keyPassword '********'
        storeFile file('googlelogindebug-keystore.jks')
        storePassword '********'
    }
}

/*
   구글 로그인 관련 키파일 설정 - 디버깅
* */
debug {
    signingConfig signingConfigs.debug
}

 

2. Firebase에 프로젝트 생성 및 설정

우선, 아까 생성한 클라우드 프로젝트를 Firebase에도 동일하게 생성시켜주도록 합니다.

 

 

이후, 1번 항목과 동일한 과정으로 App을 등록해주도록 합니다.

 

 

마지막으로, 빌드 > Authentication 항목에서 Google을 클릭하여 사용설정을 해주면 됩니다.

 

 

3. Flutter Setting

[pubspec.yaml]

dependencies:
  google_sign_in: ^5.4.1
  firebase_core: ^1.22.0
  firebase_auth: ^3.9.0

dependency에 해당 의존성을 주입시켜주도록 합니다.

로그인 및 로그아웃을 위한 함수를 분리 시켜주도록 합니다.

[google_sign_in_api.dart]

import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

class GoogleSignInApi {
  static final _googleSignIn = GoogleSignIn();

  static Future<GoogleSignInAccount?> login() {
    return _googleSignIn.signIn();
  }

  static Future logout() async {
    await FirebaseAuth.instance.signOut();
    await _googleSignIn.disconnect();
  }

}

[login.dart]

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:greeners/facebooklogin/facebook_logged_in_page.dart';
import 'package:greeners/facebooklogin/login_with_facebook.dart';
import 'package:greeners/kakaologin/kakao_logged_in_page.dart';
import 'package:greeners/kakaologin/login_with_kakao.dart';
import 'package:kakao_flutter_sdk/kakao_flutter_sdk.dart' as kakaoSdk;
import 'dart:developer' as developer;
import 'googlelogin/google_logged_in_page.dart';
import 'googlelogin/login_with_google.dart';

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

  Future<UserCredential?> loginWithGoogle(BuildContext context) async {
    GoogleSignInAccount? user = await GoogleSignInApi.login();

    GoogleSignInAuthentication? googleAuth = await user!.authentication;
    var credential = GoogleAuthProvider.credential(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken
    );

    UserCredential? userCredential = await FirebaseAuth.instance.signInWithCredential(credential);

    if (userCredential != null) {
      print('로그인 성공 === Google');
      print(userCredential);

      Navigator.of(context).pushReplacement(MaterialPageRoute(
          builder: (context) => GoogleLoggedInPage(userCredential: userCredential)
      ));
    } else {
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text('로그인 실패 === Google')
      ));
    }

    return userCredential;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SNS LOGIN'),
      ),
      body: Center(
        child: Column(
          children: [
            const SizedBox(
              height: 200,
            ),
            SizedBox(
              width: 180.0,
              height: 48.0,
              child: ElevatedButton.icon(
                style: ElevatedButton.styleFrom(
                  side: const BorderSide(
                    width: 5.0,
                    color: Colors.red,
                  ),
                  primary: Colors.white,
                  onPrimary: Colors.black,
                  minimumSize: const Size(double.infinity, 50),
                ),
                icon: const FaIcon(
                  FontAwesomeIcons.google,
                  color: Colors.red,
                ),
                label: Text('Google 로그인'),
                onPressed: () async {
                  await loginWithGoogle(context);
                },
              ),
            ),
          ],
        ),
      ),
    );
  }


}

 

필자의 경우, 버튼이 있는 화면을 별도로 만들어서 main.dart에서 해당 페이지를 호출하였습니다.

 

 

 

[google_logged_in_page.dart]

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:greeners/googlelogin/login_with_google.dart';
import 'package:greeners/login.dart';

class GoogleLoggedInPage extends StatelessWidget {
  final UserCredential userCredential;

  GoogleLoggedInPage({
    Key? key,
    required this.userCredential,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Logged In'),
        centerTitle: true,
      ),
      body: Container(
        alignment: Alignment.center,
        color: Colors.blueGrey.shade900,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextButton(
              child: const Text('Logout'),
              onPressed: () async {
                await GoogleSignInApi.logout();

                Navigator.of(context).pushReplacement(MaterialPageRoute(
                  builder: (context) => Login(),
                ));
              },
            ),
            const Text(
              'Profile',
              style: TextStyle(fontSize: 24),
            ),
            const SizedBox(height: 32),
            CircleAvatar(
                radius: 40,
                backgroundImage: NetworkImage(userCredential.user?.photoURL ??
                    'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y')),
            const SizedBox(height: 8),
            Text(
              'Name: ${userCredential.user?.displayName}',
              style: const TextStyle(color: Colors.white, fontSize: 24),
            )
          ],
        ),
      ),
    );
  }
}

 

 

여러 시행착오와 함께 해당 과정대로 하면 무리없이 Google을 통한 로그인이 되는것을 확인했습니다.

728x90

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading