feat(auth): 앱(네이티브) 구글 로그인 — @capgo/capacitor-social-login
CI / build (push) Failing after 12m48s

- 웹은 기존 GIS 유지, Capacitor 네이티브(APK)는 네이티브 구글 로그인 사용
  (웹뷰에서 GIS 팝업/FedCM 미동작 대응)
- 받은 ID 토큰은 기존과 동일하게 백엔드 /api/auth/google 로 검증
- src/lib/googleAuth.ts + LoginPage 네이티브/웹 분기

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ByungCheol
2026-07-12 11:02:51 +09:00
parent a7b633a3e5
commit 7f18d18a11
4 changed files with 85 additions and 2 deletions
+36 -2
View File
@@ -12,8 +12,20 @@
</div>
<q-card flat class="login-card q-pa-lg">
<!-- 구글 로그인 버튼(GIS 렌더링 영역) -->
<div ref="googleBtn" class="flex flex-center q-mb-md"></div>
<!-- 구글 로그인: (네이티브) 버튼, 웹은 GIS 렌더링 -->
<q-btn
v-if="isNative"
class="full-width q-py-sm q-mb-md"
color="white"
text-color="grey-9"
unelevated
icon="mdi-google"
label="Google로 계속하기"
:loading="googleLoading"
:disable="!googleClientId"
@click="onGoogleNative"
/>
<div v-else ref="googleBtn" class="flex flex-center q-mb-md"></div>
<div v-if="googleError" class="text-caption text-negative text-center q-mb-md">
{{ googleError }}
</div>
@@ -63,6 +75,7 @@ import { useAuthStore } from '@/stores/auth'
import { authApi } from '@/api/auth'
import { ApiError } from '@/api/http'
import { isAppleSignInAvailable, signInWithApple } from '@/lib/appleAuth'
import { isNativeGoogleAvailable, signInWithGoogle } from '@/lib/googleAuth'
const router = useRouter()
const route = useRoute()
@@ -71,6 +84,9 @@ const auth = useAuthStore()
const googleBtn = ref<HTMLElement | null>(null)
const googleError = ref('')
const googleClientId = ref('')
const googleLoading = ref(false)
const isNative = isNativeGoogleAvailable()
const appleLoading = ref(false)
const appleAvailable = isAppleSignInAvailable()
const devLoading = ref(false)
@@ -85,6 +101,9 @@ async function initGoogle() {
googleError.value = '구글 로그인이 아직 설정되지 않았습니다.'
return
}
googleClientId.value = clientId
// 앱(네이티브)은 버튼 클릭 시 네이티브 로그인 → GIS 초기화 불필요
if (isNative) return
await loadGsi()
const google = (window as unknown as { google: any }).google
google.accounts.id.initialize({
@@ -124,6 +143,21 @@ function loadGsi(): Promise<void> {
})
}
async function onGoogleNative() {
if (!googleClientId.value) return
googleLoading.value = true
try {
const idToken = await signInWithGoogle(googleClientId.value)
await auth.loginGoogle(idToken)
redirectAfterLogin()
} catch (e) {
if (isAppleCancel(e)) return
notifyError(e)
} finally {
googleLoading.value = false
}
}
async function onApple() {
appleLoading.value = true
try {