본문 바로가기
Develop/Android

[Android] 카카오 소셜 로그인 구현하기 (Kakao SDK)

by bona.com 2024. 7. 6.

프로젝트 <terning>에서 나는 온보딩 구현을 담당했다.

온보딩에서는 크게 소셜 로그인과 필터링 설정 기능이 들어가 있다.

 

그 중, 소셜 로그인은 카카오 소셜 로그인으로 구현했다. 

그래서 내가 카카오 소셜 로그인을 했던 과정을 전부 설명하도록 하겠다.

 

카카오 애플리케이션 등록

먼저 Kakao Developers에 접속한다.

https://developers.kakao.com/

 

Kakao Developers

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

developers.kakao.com

 

로그인 후, 내 애플리케이션으로 들어가 애플리케이션을 추가해준다.

 

이때 뜨는 창에서 프로젝트의 아이콘과 이름을 작성해주면 애플리케이션이 생성된다.

 

생성한 애플리케이션으로 들어간 후, 플랫폼 창으로 들어간다.

Android로 개발을 할 것이기 때문에 Android 플랫폼으로 등록해준다.

 

APP KEY 등록

프로젝트 settings.gradle.kts에서 다음과 같이 추가해준다.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()

        // KakaoSDK repository
        maven(url = "https://devrepo.kakao.com/nexus/content/groups/public/")
    }
}

 

그리고 라이브러리도 추가해준다.

[versions]
kakaoVersion = "2.20.1"

[libraries]
kakao-user = {group = "com.kakao.sdk", name = "v2-user", version.ref = "kakaoVersion"}

 

의존성은 최상단 app모듈과 feature 모듈에 추가해준다.

dependencies {
    implementation(libs.kakao.user)
}

 

카카오 디벨로퍼스에서 앱 키 창으로 가면 네이티브 앱 키가 생성된 것을 확인할 수 있다.

 

네이비트 앱 키를 복사해서 local.properties에 넣는다.

native.app.key ="네이티브 앱 키"
nativeAppKey = 네이티브 앱 키

 

app 모듈의 그래들에 코드를 추가해주고

android {
    defaultConfig {
        buildConfigField(
            "String",
            "NATIVE_APP_KEY",
            gradleLocalProperties(rootDir, providers).getProperty("native.app.key"),
        )
        manifestPlaceholders["NATIVE_APP_KEY"] =
            gradleLocalProperties(rootDir, providers).getProperty("nativeAppKey")
    }
}

 

매니페스트에도 추가해주면 된다.

<activity
    android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
            android:host="oauth"
            android:scheme="kakao${NATIVE_APP_KEY}" />
    </intent-filter>
</activity>

 

마지막으로 최상단 APP에 카카오 SDK를 활용할 수 있도록 작성해준다.

@HiltAndroidApp
class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()
        initKakaoSdk()
    }

    private fun initKakaoSdk() {
        KakaoSdk.init(this, BuildConfig.NATIVE_APP_KEY)
    }
}

 

키 해시 등록

카카오 로그인을 진행하기 위해서는 키 해시를 등록해줘야 한다.

다음 코드를 활용해 키 해시를 뽑을 수 있다.

var keyHash = Utility.getKeyHash(this)
Log.i("GlobalApplication", "$keyHash")

 

그리고 등록해주면 된다.

 

카카오 로그인 진행

카카오 로그인을 실행하기 위해 카카오톡 설치 유무를 먼저 확인한다.

  • 카카오톡 설치가 되어있으면 앱으로
  • 설치가 되어있지 않으면 웹으로 이동
fun startKakaoLogIn(context: Context) {
		// 앱으로 띄우기
    if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) {
        UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
            signInResult(context, token, error)
        }
    } else {
		 // 웹으로 띄우기
        UserApiClient.instance.loginWithKakaoAccount(context) { token, error ->
            signInResult(context, token, error)
        }
    }
}
  • loginWithKakaoTalk(), loginWithKakaoAccount()가 이용 동의항목을 받도록 화면을 띄운다.
  • 로그인 성공 시 OAuthToken을, 실패 시 error를 제공한다.

 

로그인 결과를 signInResult()에서 처리해준다.

  • 로그인 성공 시 OAuthToken을 가지고 로그인 서버통신 진행
  • 로그인 실패 시 signInFailure()에서 실패 처리 로직 진행
private fun signInResult(context: Context, token: OAuthToken?, error: Throwable?) {
    viewModelScope.launch {
        if (error != null) {
            signInFailure(context, error)
        } else if (token != null) {
            signInSuccess(token.accessToken)
        }
    }
}

 

카카오 로그인 실패로직

카카오 로그인 실패 로직 처리 시, 고려해야 하는 경우가 하나 더 있다.

  • 카카오톡이 설치되어 있지만, 로그인이 되어있지 않은 경우이다.

 

이를 무시하면 다음과 같은 에러가 발생한다.

AuthError(statusCode=302, reason=Unknown, response=AuthErrorResponse(error=NotSupportError, errorDescription=KakaoTalk is installed but not connected to Kakao account.))

 

그래서 이 경우 한 번 더 분기처리를 진행하여 다시 웹으로 로그인하도록 처리해줘야 한다.

private fun signInFailure(context: Context, error: Throwable?) {
    if (error.toString().contains(KAKAO_NOT_LOGGED_IN)) {
        UserApiClient.instance.loginWithKakaoAccount(context) { token, error ->
            signInResult(context, token, error)
        }
    } else {
        sigInCancellationOrError(error)
    }
}

companion object {
    private const val KAKAO_NOT_LOGGED_IN = "statusCode=302"
}

 

마지막으로 완전히 실패했을 경우 토스트를 띄워 사용자에게 알린다.

  • if (error is ClientError && error.reason == ClientErrorCause.Cancelled)문의 경우 사용자가 로그인을 시도하다가 취소했을 경우를 나타낸다.
private fun sigInCancellationOrError(error: Throwable?) {
    viewModelScope.launch {
        if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
            _signInSideEffects.emit(SignInSideEffect.ShowToast(R.string.sign_in_kakao_cancel))
        } else {
            _signInSideEffects.emit(SignInSideEffect.ShowToast(R.string.sign_in_kakao_login_fail))
        }
    }
}

 

카카오 로그인 성공로직

로그인에 성공했으면 카카오에서 받은 OAuthToken에서 accessToken을 가져와 서버통신을 진행한다.

private suspend fun signInSuccess(
    accessToken: String,
    authType: String = KAKAO,
) {
    authRepository.postSignIn(
        accessToken,
        SignInRequestModel(authType = authType)
    ).onSuccess {
       // 로그인 성공 
    }.onFailure {
       // 로그인 실패 
    }
}

companion object {
    private const val KAKAO = "KAKAO"
}

 

카카오 동의항목 받기

추가적으로 카카오 관련 항목을 이용하기 위해 필요한 것들을 설정해줘야 한다.

카카오 디벨로퍼스 대시보드 창에서 설정가능하다.

terning에서는 로그인 기능만 이용하기 때문에 카카오 로그인만 설정해주었다.