앱에서 로그인 기능은 단순한 기능 그 이상의 의미를 가집니다. 유저의 데이터를 보호하고, 개인화된 경험을 제공하며, 다양한 기능을 연동할 수 있게 하는 핵심 역할을 하죠. 특히 구글 로그인은 접근성과 신뢰성이 뛰어나기 때문에, 사용자 인증 방식으로 가장 널리 활용됩니다.
Flutter로 앱을 개발하면서 Firebase를 사용할 수도 있지만, 최근에는 Supabase를 활용해 인증과 백엔드를 관리하려는 움직임도 늘고 있어요. Supabase는 오픈소스 기반의 Firebase 대체 서비스로, 인증, 실시간 데이터베이스, 스토리지 등 다양한 기능을 제공합니다.
이번 글에서는 Flutter 앱에 Supabase를 연동해 Google 네이티브 로그인을 구현하는 방법을 단계별로 정리해보겠습니다. 특히 Android와 iOS 등 기본 플랫폼(Native)에서의 구글 로그인 흐름에 집중해, 클라이언트 ID 설정부터 Supabase 연동, 최종 로그인 처리까지 실제 동작하는 코드와 함께 안내해드릴게요.
Google 로그인을 구현하기 위한 준비 과정
Supabase로 구글 로그인을 구현하기 위해선 몇 가지 사전 준비가 필요합니다. 먼저 Google Cloud Console에서 OAuth 클라이언트 ID를 생성해야 합니다. 이때 웹, iOS, Android 각각의 플랫폼에 맞는 클라이언트 ID를 만들어야 하는데, 특히 네이티브 로그인을 구현할 경우 웹 클라이언트 ID는 필수, iOS/Android용은 선택적으로 사용됩니다.
OAuth 클라이언트 ID를 만들려면 Google Cloud 프로젝트를 생성하고, ‘사용자 인증 정보 > OAuth 2.0 클라이언트 ID 만들기’로 이동해야 합니다. 이 과정에서 플랫폼별 설정값(예: Android 패키지 이름, SHA-1 지문, iOS 번들 ID 등)을 입력하게 됩니다.
클라이언트 ID가 준비되면, Supabase 콘솔에서 해당 값을 Google 공급자 설정에 등록해야 해요. Supabase의 Authentication → Providers → Google 메뉴로 이동한 뒤, 웹 클라이언트 ID를 입력하고 저장합니다.
또한 Flutter 프로젝트에는 다음과 같은 패키지들이 필요합니다.
- google_sign_in: Google 계정 인증 처리용
- supabase_flutter: Supabase 서비스 연동용
이제 준비는 끝났습니다. 다음으로는 실제 Flutter 코드에서 Google 로그인 플로우를 구현하는 방법을 단계별로 살펴보겠습니다. 로그인을 처리하는 로직, Supabase와의 연동 방식까지 자세히 다뤄볼게요.
Flutter 코드로 Google 로그인 구현하기
Google 로그인을 위한 기본 환경이 준비되었다면, 이제 실제로 Flutter 코드 안에서 구글 로그인 → ID 토큰 획득 → Supabase 인증 처리 흐름을 구현할 차례입니다. 핵심은 단 두 가지입니다.
첫째, Google 계정으로 로그인한 후 idToken을 얻는 것.
둘째, Supabase의 signInWithIdToken 메서드를 통해 이 토큰을 사용해 인증하는 것.
이제 실제 구현 흐름을 정리해볼게요.
먼저, google_sign_in 패키지를 통해 유저가 Google 계정으로 로그인하면 GoogleSignInAccount 객체를 얻을 수 있어요. 이 객체에서 인증 정보를 요청하고, 거기서 idToken과 accessToken을 가져올 수 있습니다.
그다음, Supabase에 로그인 요청을 보내야 합니다. Supabase에서는 이 idToken을 받아서, 서버 측에서 검증한 후 JWT 토큰을 발급하고, 세션을 유지하게 됩니다.
supabase.auth.signInWithIdToken 메서드를 사용할 때는 다음 정보가 필요합니다.
- provider: “google”
- idToken: Google에서 받은 토큰
- accessToken: (선택적으로 사용 가능)
iOS에서의 네이티브 로그인, Android에서의 SHA-1 인증, 웹에서의 리디렉션 처리 등은 모두 동일한 로직으로 통일 가능하며, 플랫폼 구분 없이 동일한 로그인 함수를 사용할 수 있다는 점이 Supabase의 장점입니다.
// pubspec.yaml에 필요한 패키지 추가
// flutter pub add google_sign_in
// flutter pub add supabase_flutter
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: 'https://your-project.supabase.co',
anonKey: 'your-anon-key',
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Google Login with Supabase',
home: const LoginPage(),
);
}
}
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
Future<void> signInWithGoogle() async {
final GoogleSignIn googleSignIn = GoogleSignIn(scopes: ['email']);
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser == null) {
print('사용자가 로그인 취소함');
return;
}
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final idToken = googleAuth.idToken;
final accessToken = googleAuth.accessToken;
if (idToken == null) {
print('idToken 없음');
return;
}
final response = await Supabase.instance.client.auth.signInWithIdToken(
provider: OAuthProvider.google,
idToken: idToken,
accessToken: accessToken,
);
if (response.user != null) {
print('로그인 성공: ${response.user!.email}');
} else {
print('로그인 실패');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Supabase Google Login')),
body: Center(
child: ElevatedButton(
onPressed: signInWithGoogle,
child: const Text('Google로 로그인'),
),
),
);
}
}
이제 로그인 기능이 완성되었습니다. 구글 계정으로 로그인한 후, Supabase를 통해 세션이 유지되고, 이후에는 Supabase의 인증 토큰을 사용해 사용자 정보를 보호하거나, 서버 기능을 연동할 수 있어요.
플랫폼별 설정과 주의할 점들
Google 로그인 기능을 실제 앱에서 구현할 때 가장 많이 마주치는 문제는 ‘클라이언트 ID는 등록했는데 로그인이 안 된다’는 상황입니다. 이 대부분은 플랫폼별 설정 누락이나 오해에서 비롯되죠.
우선 iOS의 경우, Info.plist 파일에 반드시 필요한 설정을 추가해야 합니다. 여기에는 사용자의 인증 요청에 대한 설명(NSCameraUsageDescription, CFBundleURLTypes 등)과 구글 로그인과 관련된 URL Scheme 등록이 포함됩니다. 이를 누락하면 앱이 로그인을 시도하자마자 크래시가 발생하거나, 로그인 창이 아예 열리지 않기도 해요. 또한 최소 iOS 버전은 13 이상으로 설정해주는 것이 안정적인 작동을 위해 필요합니다.
Android는 SHA-1 지문 등록이 필수입니다. 디버깅 단계에서는 로컬 SHA-1 값을, 배포 전에는 Google Play 콘솔에서 발급된 릴리즈 SHA-1 지문을 Google Cloud Console의 OAuth 클라이언트 설정에 반드시 등록해야 합니다. 이 과정을 빼먹으면 로그인 창은 뜨지만 토큰을 못 받아오는 문제가 자주 발생합니다.
한 가지 유의할 점은 Android에서 Google 로그인 시 idToken이 null로 반환되는 경우가 간혹 있다는 겁니다. 이 경우에는 Google Cloud Console에서 웹 클라이언트 ID를 Android 설정에 잘못 붙여넣었거나, Supabase 콘솔에 등록한 클라이언트 ID가 일치하지 않을 가능성이 높습니다.
또한 테스트 기기에서 Google 계정이 여러 개일 경우, 권한 팝업에서 선택한 계정이 이전에 거절됐거나 제대로 연동되지 않은 경우, 토큰 요청에 실패할 수 있으니 로그인 전에 캐시를 지우거나 로그아웃 후 재시도해보는 것도 좋은 방법이에요.
마지막으로, 실제 배포 전에는 웹 클라이언트 ID, iOS 번들 ID, Android 패키지 이름과 SHA-1 모두가 정확히 등록되어 있는지 Supabase 콘솔과 Google Cloud 콘솔을 다시 한 번 교차 확인하는 습관이 필요합니다. 단 한 글자의 오타나 누락도 로그인을 막을 수 있으니까요.
마치며...
Flutter에서 Supabase를 활용한 Google 로그인은 단순히 로그인을 구현하는 기술 이상의 의미를 가집니다. 이 기능은 앱의 첫인상이며, 사용자가 앱과 맺는 신뢰의 첫 번째 접점이기도 해요. 로그인 과정이 매끄럽고 안정적이라면, 사용자는 자연스럽게 다음 화면으로 이어지고, 그 안에서 브랜드에 대한 긍정적인 인상을 갖게 됩니다.
Supabase는 비교적 쉽게 인증 기능을 구성할 수 있는 강력한 도구입니다. 특히 구글 로그인을 비롯한 소셜 로그인 기능을 단 몇 줄의 코드로 구현할 수 있다는 점은 개발자의 생산성을 높이고, 유지보수를 훨씬 수월하게 만들어줍니다.
물론 처음 설정할 때는 다소 헷갈릴 수 있습니다. Google Cloud 설정, 클라이언트 ID 발급, Info.plist, SHA-1, Supabase 콘솔 등 손댈 것이 많으니까요. 하지만 그 과정을 천천히 따라가다 보면, 크게 어렵지 않게 로그인이 필요한 서비스를 구축할 수 있을 거예요!
'IT' 카테고리의 다른 글
플러터, 크래시리틱스로 유지보수하기 (0) | 2025.05.12 |
---|---|
플러터, 유저에게 알림 보내기 (2) | 2025.05.08 |
플러터, Gemini API 연동하기 (0) | 2025.05.07 |
바이브 코딩은 세상을 어떻게 바꿀까? (0) | 2025.05.06 |
플러터, 쓰로틀링과 디바운싱 (0) | 2025.05.02 |