계정 탈퇴

김동연·2025년 6월 23일

개발기록일지(Flutter)

목록 보기
21/32

1. 구글(Google) 계정 연동 해제 및 탈퇴

1-1. 연동 해제(Revoke)란?

  • 구글 계정 연동 해제란, 내 앱이 구글 계정 정보(프로필/이메일 등)에 접근할 수 있는 권한을 명시적으로 취소하는 작업.
  • 일반적으로 Firebase Auth로 구글 로그인 시,
    단순히 Firebase의 user.delete() 또는 signOut()만 해도 실제 구글 계정에서는 앱 연결이 유지됨.
  • 진짜 권한 해제를 원하면 access token을 구글 Revoke API로 요청해야 함.

1-2. Flutter/Firebase에서 구글 계정 탈퇴 흐름

(1) Firestore/로컬 데이터 삭제

  • 유저의 Firestore 데이터를 모두 삭제

(2) 구글 access_token을 사용해 revoke

  • 구글 로그인할 때 GoogleSignInAccount로부터 accessToken을 획득,
    이후 아래 API로 연동 해제 요청

    GET https://accounts.google.com/o/oauth2/revoke?token={access_token}
  • 성공 시, 앱과 계정의 연결이 실제로 끊김

  • 실제로 연결이 끊겼는지 확인 필요

(3) Firebase Auth 계정 삭제

  • FirebaseAuth.instance.currentUser?.delete()

    • 단, 최근 로그인(reauthenticate)이 필요할 수 있음.

(4) SharedPreferences 등 클린업

  • 로그인 정보, provider, userId 등 앱 내 모든 세션/캐시 삭제

예시 코드

Future<void> deleteGoogleAccount() async {
  // 1. Firestore 데이터 삭제 (이미 구현됨)

  // 2. accessToken으로 revoke
  final googleAccessToken = await getGoogleAccessToken();
  if (googleAccessToken != null) {
    await revokeGoogleToken(googleAccessToken); // 성공/실패 무관 진행
  }

  // 3. Firebase 계정 삭제
  final user = FirebaseAuth.instance.currentUser;
  if (user != null) {
    try {
      await user.delete();
    } on FirebaseAuthException catch (e) {
      // recent-login error 처리 필요 (reauthenticate)
      if (e.code == 'requires-recent-login') {
        // 재로그인 안내 or 자동 signOut
      }
    }
  }

  // 4. SharedPreferences/Provider 초기화
  await signOut();
}

2. 카카오(Kakao) 계정 연동 해제 및 탈퇴

2-1. 카카오 계정 연동 해제란?

  • 카카오 계정 연동 해제란, 내 앱이 카카오 계정의 정보에 접근할 수 있는 권한을 명시적으로 끊는 것.
  • 카카오 SDK 공식
    → 유저 본인 인증 이후 unlink API 호출

2-2. Flutter(Kakao SDK)에서 카카오 계정 탈퇴 흐름

(1) Firestore/로컬 데이터 삭제

  • 구글과 동일하게 Firestore 데이터 삭제

(2) 카카오 API를 통한 연동 해제

  • Flutter에서는 kakao_flutter_sdk_user
    UserApi.instance.unlink() 메서드 사용
  • 토큰이 만료/삭제되어 있더라도, 이미 해제된 경우도 예외 처리 필요

(3) Firebase Auth 계정 삭제 (연동된 경우)

  • 만약 카카오로 Firebase Auth 연동을 사용한다면,
    Firebase 계정 삭제도 함께 필요

(4) SharedPreferences 등 클린업

  • userId, provider 등 앱 내 세션 데이터 초기화

예시 코드

Future<void> deleteKakaoAccount() async {
  // 1. Firestore 데이터 삭제 (이미 구현됨)

  // 2. 카카오 연동 해제
  try {
    await UserApi.instance.unlink();
  } catch (e) {
    // 이미 해제된 상태이거나, 에러 무시
  }

  // 3. (필요 시) Firebase 계정 삭제
  final user = FirebaseAuth.instance.currentUser;
  if (user != null) {
    try {
      await user.delete();
    } on FirebaseAuthException catch (e) {
      if (e.code == 'requires-recent-login') {
        // 재로그인 안내 or 자동 signOut
      }
    }
  }

  // 4. SharedPreferences/Provider 초기화
  await signOut();
}

3. 구글/카카오 계정 탈퇴 로직 정리 표

순서공통 단계GoogleKakao
1Firestore 데이터 삭제OO
2계정 연동 해제access_token으로 revoke API 호출UserApi.instance.unlink() 호출
3Firebase Auth 삭제currentUser.delete()currentUser.delete() (연동 시만)
4앱 내 세션/캐시 삭제signOut(), SharedPreferences.clear() 등signOut(), SharedPreferences.clear() 등

애플 계정 탈퇴 같은 경우는 제대로 구현하지 못함. 추후 작성

  • Google:

    • revoke 요청이 400 에러(토큰 만료)여도, 어차피 Firebase 계정 삭제는 별도이므로 무시 가능
    • currentUser.delete()에서 requires-recent-login 발생 시 반드시 재로그인 요구
  • Kakao:

    • UserApi.instance.unlink()가 실패해도, 이미 해제된 계정이면 무시
    • 카카오 계정 자체 삭제가 아니라 앱과의 연결 해제임 (카카오 계정은 유지)
    • Firebase Auth와 연결된 경우, 별도로 삭제 필요
  • 공통:

    • Firestore 등 DB에 남은 데이터 반드시 모두 삭제
    • 모든 세션/SharedPreferences/Provider 값 초기화(로그아웃 후 재로그인 시 유령 데이터 방지)
    • Flutter 쪽에서 실제로 계정이 완전히 삭제됐는지 확인
      네, 정확히 앱마다 실제 동작이 다를 수 있습니다.
      그리고 Apple 로그인 시 동의 항목(이름/이메일 제공 등)은 “최초 연동 시 1회만” 물어보고, 이후에는 다시 물어보지 않는 것이 일반적입니다.

관련 질문들

1. “Apple은 원래 동의 항목을 안 물어보나?”

Apple 로그인 동의항목 안내는 다음과 같습니다.

  • 최초 “Apple로 로그인” 시

    • 이름/이메일 제공 동의
    • “가려진 이메일”(privaterelay.appleid.com) 사용 여부 선택
  • 이미 연동된 앱에 재로그인

    • 동의 항목을 다시 물어보지 않습니다.
    • 재로그인 하더라도 정보를 가져오지 못하는 경우가 있음. 따라서 계정탈퇴시 유의해야함.
    • 이미 userIdentifier와(필요시) 이메일 정보가 앱 서버에 남아있는 경우도 있음.

즉, “동의 항목”은 최초 1회만 물어봅니다. 연동 해제 후 재로그인에서도, Apple 계정 입장에서는 ‘이전에 이 앱에 권한을 부여했었는지’만 체크해서 이미 부여했다면 추가 동의를 요구하지 않습니다.

카카오 같은 경우에는 재로그인 시 동의항목을 항상 물어봄.


2. 앱마다 다른 동작

  • 어떤 앱은 “연동 해제” 시 계정 정보까지 완전히 삭제
    → 이 경우에는 다음 로그인 때 “신규 가입” 절차가 다시 뜰 수도 있음
  • 어떤 앱은 “연동 해제” 시 연동만 끊고, 계정 정보는 그대로 유지
    → 이 경우에는 다시 로그인 시 기존 계정으로 바로 접속

정리

  • Apple로 로그인 연동 해제 → 다시 로그인

    • 앱이 userIdentifier 기준으로 계정 데이터를 삭제하지 않았다면
      로그아웃/로그인과 거의 같음 (비밀번호 입력, 동의항목 생략)
    • 계정이 완전히 삭제된 경우
      신규가입 절차가 나옴, 이때만 동의항목 재요구
  • Apple은 동의항목을 “최초 1회”만 묻고, 그 이후에는 재로그인 시 따로 안 묻는 것이 정상 동작


5. 샘플 구조화된 코드 (실제 코드와 다름)

Future<void> deleteUserAccount(String provider) async {
  // 1. Firestore 데이터 삭제 (공통)
  await deleteAllUserDataFromFirestore();

  // 2. 각 SNS 별 연동 해제
  if (provider == 'google') {
    final googleAccessToken = await getGoogleAccessToken();
    if (googleAccessToken != null) {
      await revokeGoogleToken(googleAccessToken);
    }
  } else if (provider == 'kakao') {
    try {
      await UserApi.instance.unlink();
    } catch (_) {}
  }

  // 3. Firebase Auth 삭제
  final user = FirebaseAuth.instance.currentUser;
  if (user != null) {
    try {
      await user.delete();
    } on FirebaseAuthException catch (e) {
      if (e.code == 'requires-recent-login') {
        // 재로그인 필요
      }
    }
  }

  // 4. 앱 세션 초기화
  await signOut();
}

0개의 댓글