Flutter에서 카카오 로그인 구현하기

sumong·2023년 1월 12일
7
post-thumbnail

참고 자료
카카오 로그인 Flutter SDK 공식문서


카카오 로그인 또한 코딩 이전까지의 과정이 험난합니다....... 잘 따라와주세요!


사전 준비

플랫폼 등록

Kakao Developers 공식문서 : 시작하기 > 플랫폼 등록

위 링크에 더 자세한 설명이 있습니다. 여기서는 최대한 핵심만 알려드리고 넘어가겠습니다.

  1. 카카오 개발자 페이지에 들어가서 로그인합니다.

  2. 내 애플리케이션에 들어가서 새로운 앱을 만듭니다.

  3. ‘플랫폼’ 메뉴에 들어갑니다.

  4. 안드로이드 앱부터 등록해봅시다. ‘Android 플랫폼 등록'을 누릅니다.

  5. 아래의 정보들을 입력합니다.

    • 패키지명 : 안드로이드 앱 패키지명.
      프로젝트 폴더의 android - app - src - main - AndroidManifest.xml 파일을 열고, 해당 파일 최상단 태그의 package에 해당하는 값을 입력하시면 됩니다.
    • 마켓 URL : 공백으로 놓으면 됩니다.
    • 키 해시 : 앱이 아직 개발중이고, 한 번도 배포한 적이 없다면 디버그용 키 해시만 입력하시면 됩니다. 반면, 앱을 배포한 적이 있거나, 배포 상태로 테스트하려면 디버그용 키 해시와 릴리즈용 키 해시 둘 다를 입력하셔야 합니다. 각 키 해시를 얻는 방법은 아래 링크를 참고해주세요!
      - 디버그용 : https://machine-woong.tistory.com/420
      - 릴리즈용 : https://songjang.tistory.com/53
  6. 안드로이드 등록을 마쳤으면, 이번엔 ‘iOS 플랫폼 등록'을 눌러서 iOS 앱 등록으로 넘어갑니다.

  7. 다른 건 다 공란으로 두고, 번들 ID만 입력해주고 ‘저장'을 누릅니다.
    iOS 번들 ID 찾는 방법 : https://velog.io/@adbr/flutter-firebase-ios-앱추가



카카오 로그인 활성화

Kakao Developers 공식문서 링크

  1. ‘카카오 로그인’ 메뉴를 클릭합니다.
  2. ‘활성화 설정'에 OFF로 되어 있는데 이를 클릭합니다.
  3. ‘활성화'를 클릭합니다.


동의 항목 작성

Kakao Developers 공식문서 링크

⚠️ 출생 연도, 전화번호 등 몇몇 정보는 비즈 앱으로 전환하지 않으면 받을 수 없습니다.
만약 이런 정보들을 받고 싶으시다면, 현재 앱을 비즈 앱으로 전환한 뒤에 검수를 통과하셔야 합니다.

  1. ‘카카오 로그인’ 밑의 ‘동의항목'을 클릭합니다.
  2. 아래 개인정보 표 중에서 받아야 하는 정보가 있다면 ‘설정' 버튼을 누릅니다.

  3. 아래와 같은 화면이 나오는데, 동의 단계 및 동의 목적(데이터를 받아야 하는 이유)를 기록한 뒤 ‘저장'을 누릅니다.
    받아야 하는 모든 데이터에 대해 이 작업을 하시면 됩니다.


Kakao SDK 추가

  1. pubspec.yaml에 라이브러리를 추가합니다. 아래 두 코드 중 하나를 사용하시면 됩니다.
    Kakao Flutter SDK 최신버전 확인하기
#2023.01.13 기준 가장 최신 버전은 1.3.1
dependencies:
	# 모든 카카오 라이브러리 추가를 원하는 경우
	kakao_flutter_sdk: ^1.3.1
dependencies:
	# 카카오 로그인만 추가하는 경우
	kakao_flutter_sdk_user: ^1.3.1
  1. main 함수에 Kakao Flutter SDK 초기화 코드를 추가합니다.
    단, runApp() 메서드 호출 전에 Flutter SDK를 초기화해야 합니다!
    ${YOUR_NATIVE_APP_KEY} 부분에는 [내 애플리케이션] > [앱 키]에서 확인한 네이티브 앱 키를 입력합니다.

void main() {
  ...
  KakaoSdk.init(nativeAppKey: '${YOUR_NATIVE_APP_KEY}'); // 이 줄을 runApp 위에 추가한다.
  runApp(MyApp());
  ...
}

네이티브 앱 키는 내 애플리케이션에 들어가면 있습니다.
아래 표에서 ‘네이티브 앱 키’를 위 코드의 ${YOUR_NATIVE_APP_KEY}에 넣으면 됩니다.

  1. 안드로이드 앱에 대한 설정을 추가합니다.
    a. android/app/src/AndroidManifest.xml 에 카카오 로그인 Redirect URI를 추가해야 합니다. 해당 파일의application 태그 안에 새로운 activity 태그를 아래 예제와 같이 추가합니다.
    ${YOUR_NATIVE_APP_KEY}부분에는 [내 애플리케이션] > [앱 키]에서 확인한 네이티브 앱 키를 입력합니다.
<activity android:name="com.kakao.sdk.flutter.AuthCodeCustomTabsActivity">
	<intent-filter android:label="flutter_web_auth">
		<action android:name="android.intent.action.VIEW" />
		<category android:name="android.intent.category.DEFAULT" />
		<category android:name="android.intent.category.BROWSABLE" />
    
		<!-- Redirect URI, "kakao${YOUR_NATIVE_APP_KEY}://oauth" 형식 -->
		<data android:scheme="kakao${YOUR_NATIVE_APP_KEY}" android:host="oauth"/>
	</intent-filter>
</activity>
  1. iOS 앱에 대한 설정을 추가합니다.
    a. iOS 폴더에 대고 마우스 오른쪽 클릭 - [Flutter] - [Open iOS module in Xcode]을 클릭해서 iOS용 프로젝트를 엽니다.
    b. 앱 실행 허용 목록 설정하기 : Runner로 이동한 뒤, Info 탭을 누릅니다. 이후, Custom iOS Target Properties 항목에 Array 타입 키(Key)인 LSApplicationQueriesSchemes를 추가하고, 해당 키의 [Item]으로 커스텀 URL 스킴에 사용할 값인 "kakaokompassauth", "kakaolink"를 추가합니다.
    추가하면 아래와 같은 모습이 됩니다.
    c. URL Schemes 설정하기 : 위의 Info 탭에서 맨 아래에 있는 URL Types를 엽니다. 이후, [URL Schemes] 항목에 네이티브 앱 키(Native App Key)를 kakao${NATIVE_APP_KEY} 형식으로 등록합니다. 예를 들어 네이티브 앱 키가 "123456789"라면 [URL Schemes]에 "kakao123456789"를 입력합니다.
    (참고로, 기존 Scheme가 존재한다면 새로 추가해서 입력하시면 됩니다.)

코드 작성

드디어 설정 끝! 이제 코드를 작성해 봅시다.

Kakao Developers 공식문서 링크 : 카카오톡으로 로그인

로그인 구현 예제

// 카카오 로그인 구현 예제

// 카카오톡 설치 여부 확인
// 카카오톡이 설치되어 있으면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인
if (await isKakaoTalkInstalled()) {
  try {
      await UserApi.instance.loginWithKakaoTalk();
      print('카카오톡으로 로그인 성공');
  } catch (error) {
    print('카카오톡으로 로그인 실패 $error');

    // 사용자가 카카오톡 설치 후 디바이스 권한 요청 화면에서 로그인을 취소한 경우,
    // 의도적인 로그인 취소로 보고 카카오계정으로 로그인 시도 없이 로그인 취소로 처리 (예: 뒤로 가기)
    if (error is PlatformException && error.code == 'CANCELED') {
        return;
    }
    // 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인
    try {
        await UserApi.instance.loginWithKakaoAccount();
        print('카카오계정으로 로그인 성공');
    } catch (error) {
        print('카카오계정으로 로그인 실패 $error');
    }
  }
} else {
  try {
    await UserApi.instance.loginWithKakaoAccount();
    print('카카오계정으로 로그인 성공');
  } catch (error) {
    print('카카오계정으로 로그인 실패 $error');
  }
}

사용자 정보 가져오기

주의 : 모든 정보를 다 가져올 수 있는 건 아닙니다. 다음의 경우 정보를 가져오지 못할 수 있으며, 이런 경우에 대한 예외처리가 별도로 필요합니다!

  • 동의 항목 미설정
  • 사용자 미동의
  • 사용자가 카카오에 제공하지 않은 정보
try {
  User user = await UserApi.instance.me();
  print('사용자 정보 요청 성공'
        '\n회원번호: ${user.id}'
        '\n닉네임: ${user.kakaoAccount?.profile?.nickname}'
        '\n이메일: ${user.kakaoAccount?.email}');
} catch (error) {
  print('사용자 정보 요청 실패 $error');
}

<주의 사항>
: 사용자로부터 무조건 받아올 수 있는 카카오 계정 닉네임은 user.kakaoAccount?.profile?.nickname 입니다.
user.kakaoAccount?.name이 아닙니다! (이거 때문에 한참 해멨습니다. 이 name값은 nullable한 값입니다.)

추가 항목 동의 받기

User user;

  try {
    user = await UserApi.instance.me();
  } catch (error) {
    print('사용자 정보 요청 실패 $error');
    return;
  }

  List<String> scopes = [];

  if (user.kakaoAccount?.emailNeedsAgreement == true) {
    scopes.add('account_email');
  }
  if (user.kakaoAccount?.birthdayNeedsAgreement == true) {
    scopes.add("birthday");
  }
  if (user.kakaoAccount?.birthyearNeedsAgreement == true) {
    scopes.add("birthyear");
  }
  if (user.kakaoAccount?.ciNeedsAgreement == true) {
    scopes.add("account_ci");
  }
  if (user.kakaoAccount?.phoneNumberNeedsAgreement == true) {
    scopes.add("phone_number");
  }
  if (user.kakaoAccount?.profileNeedsAgreement == true) {
    scopes.add("profile");
  }
  if (user.kakaoAccount?.ageRangeNeedsAgreement == true) {
    scopes.add("age_range");
  }

  if (scopes.length > 0) {
    print('사용자에게 추가 동의 받아야 하는 항목이 있습니다');

    // OpenID Connect 사용 시
    // scope 목록에 "openid" 문자열을 추가하고 요청해야 함
    // 해당 문자열을 포함하지 않은 경우, ID 토큰이 재발급되지 않음
    // scopes.add("openid")

    //scope 목록을 전달하여 카카오 로그인 요청
    OAuthToken token;
    try {
      token = await UserApi.instance.loginWithNewScopes(scopes);
      print('현재 사용자가 동의한 동의 항목: ${token.scopes}');
    } catch (error) {
      print('추가 동의 요청 실패 $error');
      return;
    }

    // 사용자 정보 재요청
    try {
      User user = await UserApi.instance.me();
      print('사용자 정보 요청 성공'
          '\n회원번호: ${user.id}'
          '\n닉네임: ${user.kakaoAccount?.profile?.nickname}'
          '\n이메일: ${user.kakaoAccount?.email}');
    } catch (error) {
      print('사용자 정보 요청 실패 $error');
    }
  }
profile
Flutter 메인의 풀스택 개발자 / 한양대 컴퓨터소프트웨어학과, HUHS의 화석

2개의 댓글

comment-user-thumbnail
2024년 3월 15일

카카오톡으로 이동되었다가 바로 앱으로 돌아옵니다.. 에러가 나진 않아요. 왜 이럴까요???
키값도 잘 입력했습니다 ㅜㅜ

1개의 답글