앱/flutter

[flutter/kakao login/android] 플러터 안드로이드 앱에 카카오 로그인 적용하기

일 월 2023. 8. 7. 07:58

https://developers.kakao.com/docs/latest/ko/kakaologin/flutter

 

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

* 안드로이드 앱 위주로 설명되어 있습니다.


플랫폼 정보 등록

개발자 웹 사이트에 로그인 한 후, [내 애플리케이션] > [애플리케이션 추가하기]에서 앱을 생성한다. 이 기본 정보는 카카오 로그인 동의 화면, 연결된 서비스 관리, 카카오톡 메시지 하단의 출처 등에 표시된다고 한다.

애플리케이션 추가하기 (출처 : https://developers.kakao.com/docs/latest/ko/getting-started)


플랫폼 등록

[내 애플리케이션] > [플랫폼] 메뉴에서 서비스에 필요한 플랫폼을 등록한다.

패키지명

패키지명은 AndroidManifest.xml에 있는데, 초기값은 'com.example.패키지명'이다. 패키지명은 playstore에 등록할 때 id 값으로 사용되고, 등록 전에 변경가능하다. (패키지명은 AndroidManifest.xml에만 있는 것이 아니라서, vs code 검색 기능을 이용해 example 검색해서 모든 패키지명을 변경해줬다.)

안드로이드 플랫폼 등록 (출처 : https://developers.kakao.com/docs/latest/ko/getting-started)

마켓 URL

앱을 등록한 마켓 url을 넣어주면 되는데, 디버그 모드에서는 입력하지 않아도 된다. 링크를 통해 앱을 실행시킬 때, 앱이 설치되어 있지 않을 경우, 이 주소로 이동한다고 한다.

 

키 해시

개발 및 서비스 릴리즈 빌드를 위해 필요한 키 해시 값으로, 카카오 API 요청 시 유효성 검증에 사용되며, 개발 환경별로 등록해야 한다.

 

https://developers.kakao.com/docs/latest/ko/getting-started/sdk-android#add-key-hash

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

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

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

 

위의 명령어로 디버그 키 해시를 생성할 수 있다. (릴리즈 키는 마켓에 등록한 후에 생성해도 된다. 마켓에 등록한 후에는 터미널에 명령어를 치지 않고 Google Play 앱 서명으로 키 해시를 확인하는 방법을 이용했다.)

 

생성한 디버그, 릴리즈 키 해시 값들을 개발자 웹사이트의 [내 애플리케이션] > [플랫폼] > [Android]에 모두 등록하면 간단하게 끝날 것 같지만, 계속 invalid_key_hash가 뜨는 오류가 발생했다. kakao sdk로 키 해시를 확인하는 방법을 이용해 오류를 해결할 수 있었다. 이 방법은 초기화 이후에 사용해야 하므로, 초기화 파트에 넣어뒀다

 

만약 여러 명의 개발자가 앱의 개발에 참여하고 있다면 각 개발자들의 개발 환경에 따라 디버그 키스토어(keystore)가 각자 다르므로 각 디버그 키 해시를 모두 등록해야 합니다.

위 문구에서 로그인을 사용하지 않을 프론트엔드 개발자도 등록해야 하나? 백엔드 개발자도 등록해야 하나? 이런 의문이 들었다. 백엔드 개발자, 로그인을 사용하지 않는 기능을 담당하는 프론트엔드 개발자는 등록하지 않아도 괜찮았다. 로그인 기능을 사용할 때, QA를 진행할 때 등록하는 방식으로 진행했다.


팀원 등록 (선택 사항)

[내 애플리케이션] > [팀 관리] 메뉴의 [팀원 초대] 버튼을 눌러 팀원을 추가할 수 있다. 카카오 콘솔에 OWNER로 등록된 계정이 다른 팀원 계정이라, 설정된 값을 확인할 때 다른 팀원의 도움이 필요했는데, 팀원 등록을 하니 내 계정으로도 앱 정보를 확인, 수정할 수 있어 편리했다.

팀 관리 (출처 : https://developers.kakao.com/docs/latest/ko/getting-started)

 


패키지 설치

pubspec.yaml 파일의 dependencies 하위에 Flutter SDK에 대한 의존성을 추가하거나, flutter 프로젝트가 위치하는 곳에서 터미널에 flutter pub add kakao_flutter_sdk 명령어를 입력한다. 카카오 로그인만 사용할 예정이라, 전체 추가가 아니라 카카오 로그인만 설치해주었다.

// 둘 중 하나만 선택해 설치
dependencies:
  kakao_flutter_sdk: ^1.4.1 # 전체 추가
  kakao_flutter_sdk_user: ^1.4.1 # 카카오 로그인

커스텀 URL 스킴 설정

네이티브 앱 키는 카카오 콘솔 - 내 애플리케이션 - 앱 설정 - 앱 키에서 확인할 수 있다.

네이티브 앱 키 (출처 : https://developers.kakao.com/docs/latest/ko/getting-started)

//프로젝트 폴더 > android > app > src 경로 내부의 AndroidManifest.xml

<application>

    <!-- 카카오 로그인 커스텀 URL 스킴 설정 -->
    <activity 
        android:name="com.kakao.sdk.flutter.AuthCodeCustomTabsActivity"
        android:exported="true">
        <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" />

            <!-- "kakao${YOUR_NATIVE_APP_KEY}://oauth" 형식의 앱 실행 스킴 설정 -->
            <!-- 카카오 로그인 Redirect URI -->
            <data android:scheme="kakao${YOUR_NATIVE_APP_KEY}" android:host="oauth"/>
        </intent-filter>
    </activity>

</application>

네이티브 앱 키를 등록할 때 주의할 점은, 네이티브 앱 키가 1234라면 "kakao${1234}"가 아니라 "kakao1234"로  입력해야 한다는 점이다.

 


초기화

앱만 서비스할 예정이라 javaScriptAppKey는 등록하지 않았다. 카카오 콘솔 - 내 애플리케이션 - 앱 설정 - 앱 키에서 네이티브 키를 복사해 넣어준다.

import 'package:kakao_flutter_sdk_common/kakao_flutter_sdk_common.dart';

void main() {
    ...
    // 웹 환경에서 카카오 로그인을 정상적으로 완료하려면 runApp() 호출 전 아래 메서드 호출 필요
    WidgetsFlutterBinding.ensureInitialized();

    // runApp() 호출 전 Flutter SDK 초기화
    KakaoSdk.init(
        nativeAppKey: '${YOUR_NATIVE_APP_KEY}', // 앱 서비스 시 필요
        javaScriptAppKey: '${YOUR_JAVASCRIPT_APP_KEY}', // 웹 서비스 시 필요
    );
    // 키 해시 출력
    print(await KakaoSdk.origin);
    runApp(MyApp());
    ...
}

키 해시가 카카오 콘솔에 등록되어 있는 키 해시와 동일한지 확인하고, 동일하지 않으면 변경해준다.

 

네이티브 앱 키가 깃허브에 올라가는 걸 방지하기 위해 .env 파일에 네이티브 앱 키를 넣어주고, 이를 main.dart에서 참조하는 방식으로 구현해주었다.

// 프로젝트 > pubspec.yaml
dependencies:
  flutter_dotenv: ^5.0.2

// 프로젝트 > .env
nativeAppKey = '네이티브 앱 키'

// 프로젝트 > .gitignore
.env

// 프로젝트 > lib > main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await dotenv.load(fileName: '.env');
  KakaoSdk.init(nativeAppKey: dotenv.env['nativeAppKey']);
  print(await KakaoSdk.origin); // 확인 후 삭제
  runApp(const App());
}

구현 방식

앱에 적용하기 위해 redirect 방식이 아닌 기본 방식 (클라이언트에서 인가 코드 및 토큰 발급 모두 처리하는 방식)을 이용했다. 카카오계정을 인증하는 방식은 아래 방식을 참고해 카카오톡으로 로그인과 카카오계정 로그인을 모두 사용하도록 했다.

// 카카오 로그인 구현 예제 (출처 : 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');
  }
}