본문 바로가기
🖥 Programming/📱 Android (Kotlin)

[Android][Kotlin] 카카오 로그인 API연동(Kakao Login) - 3

by MinChan-Youn 2022. 2. 10.

안녕하세요 챠니코딩입니다~

이번 게시글은 안드로이드 개발자라면 알아두면 서비스개발에서 한번쯤은 꼭 사용하는 KakaoLogin을 구현하는 방법에 대해서 알아보겠습니다. - 3편

 

 

카카오 로그인 API 예제코드

Git:https://github.com/younminchan/kotlin-sns-samples/tree/main/kotlin-kakao-login

 

공식 API 문서

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

https://developers.kakao.com/docs/latest/ko/getting-started/sdk-android

 

Kakao Developers

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

developers.kakao.com

 

 

3-1. MainActivity.kt

//MainActivity.kt
class MainActivity : AppCompatActivity() {
    private var _binding: ActivityMainBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        _binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        /** HashKey확인 */
        val keyHash = Utility.getKeyHash(this)
        TextMsg(this, "HashKey: ${keyHash}")

        /** KakoSDK init */
        KakaoSdk.init(this, this.getString(R.string.kakao_app_key))

        /** Click_listener */
        binding.btnStartKakaoLogin.setOnClickListener {
            kakaoLogin() //로그인
        }
        binding.btnStartKakaoLogout.setOnClickListener {
            kakaoLogout() //로그아웃
        }
        binding.btnStartKakaoUnlink.setOnClickListener {
            kakaoUnlink() //연결해제
        }
    }

    private fun kakaoLogin() {
        // 카카오계정으로 로그인 공통 callback 구성
        // 카카오톡으로 로그인 할 수 없어 카카오계정으로 로그인할 경우 사용됨
        val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
            if (error != null) {
                TextMsg(this, "카카오계정으로 로그인 실패 : ${error}")
                setLogin(false)
            } else if (token != null) {
                //TODO: 최종적으로 카카오로그인 및 유저정보 가져온 결과
                UserApiClient.instance.me { user, error ->
                    TextMsg(this, "카카오계정으로 로그인 성공 \n\n " +
                            "token: ${token.accessToken} \n\n " +
                            "me: ${user}")
                    setLogin(true)
                }
            }
        }

        // 카카오톡이 설치되어 있으면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인
        if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) {
            UserApiClient.instance.loginWithKakaoTalk(this) { token, error ->
                if (error != null) {
                    TextMsg(this, "카카오톡으로 로그인 실패 : ${error}")

                    // 사용자가 카카오톡 설치 후 디바이스 권한 요청 화면에서 로그인을 취소한 경우,
                    // 의도적인 로그인 취소로 보고 카카오계정으로 로그인 시도 없이 로그인 취소로 처리 (예: 뒤로 가기)
                    if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
                        return@loginWithKakaoTalk
                    }

                    // 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인 시도
                    UserApiClient.instance.loginWithKakaoAccount(this, callback = callback)
                } else if (token != null) {
                    TextMsg(this, "카카오톡으로 로그인 성공 ${token.accessToken}")
                    setLogin(true)
                }
            }
        } else {
            UserApiClient.instance.loginWithKakaoAccount(this, callback = callback)
        }
    }

    private fun kakaoLogout(){
        // 로그아웃
        UserApiClient.instance.logout { error ->
            if (error != null) {
                TextMsg(this, "로그아웃 실패. SDK에서 토큰 삭제됨: ${error}")
            }
            else {
                TextMsg(this, "로그아웃 성공. SDK에서 토큰 삭제됨")
                setLogin(false)
            }
        }
    }

    private fun kakaoUnlink(){
        // 연결 끊기
        UserApiClient.instance.unlink { error ->
            if (error != null) {
                TextMsg(this, "연결 끊기 실패: ${error}")
            }
            else {
                TextMsg(this, "연결 끊기 성공. SDK에서 토큰 삭제 됨")
                setLogin(false)
            }
        }
    }

    private fun TextMsg(act: Activity, msg : String){
        binding.tvHashKey.text = msg
    }

    private fun setLogin(bool: Boolean){
        binding.btnStartKakaoLogin.visibility = if(bool) View.GONE else View.VISIBLE
        binding.btnStartKakaoLogout.visibility = if(bool) View.VISIBLE else View.GONE
        binding.btnStartKakaoUnlink.visibility = if(bool) View.VISIBLE else View.GONE
    }
}

 

3-2. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_start_kakao_login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="10dp"
        android:backgroundTint="#f9e000"
        android:text="카카오 로그인"
        android:textColor="@color/white"
        android:textSize="20dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_start_kakao_logout"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="10dp"
        android:backgroundTint="#f9e000"
        android:text="카카오 로그아웃"
        android:textColor="@color/white"
        android:textSize="20dp"
        android:textStyle="bold"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_start_kakao_login" />

    <Button
        android:id="@+id/btn_start_kakao_unlink"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="10dp"
        android:backgroundTint="#f9e000"
        android:text="카카오 연결끊기"
        android:textColor="@color/white"
        android:textSize="20dp"
        android:textStyle="bold"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_start_kakao_logout" />

    <TextView
        android:id="@+id/tv_hashKey"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="text"
        android:textColor="@color/black"
        android:textSize="14dp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_start_kakao_unlink" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

3-3. Strings.xml - (중점: kakao_app_key)

<resources>
    <string name="app_name">kotlin-kakao-login</string>

    <!-- Kakao KEY설정[AndroidManifest.xml에도 설정]-->
    <!-- Kakao-init에서 사용 -->
    <string name="kakao_app_key">{NATIVE_APP_KEY}}</string>
    <!-- AndroidManifest.xml에서 사용 -->
    <string name="kakao_app_key2">kakao{NATIVE_APP_KEY}</string>

</resources>

 

3-4. AndroidManifest.xml - (중점: 인터넷 사용 권한, KakaoLogin activity, Kakao_app_key)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.kotlin_kakao_login">

    <!-- 인터넷 사용 권한 설정-->
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Kotlinkakaologin">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Kakao 로그인 -->
        <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" />

                <!-- Redirect URI: "kakao{NATIVE_APP_KEY}://oauth" -->
                <!-- scheme-example: "kakao{NATIVE_APP_KEY}" -->
                <data
                    android:host="oauth"
                    android:scheme="@string/kakao_app_key2" />

            </intent-filter>
        </activity>

    </application>

</manifest>

 

*결과물

카카오 로그인 전
카카오 로그인 후

 

여기까지 따라오셨다면 여러분은 카카오 로그인API에 대해서 이해를 하고 구현을 하시는데 문제가 없을것입니다~

 

 

----------------------------------------------------------------------------------------------------------

게시글의 궁굼한 점 또는 도움이 되었다면 댓글을 남겨주시면 답변드리겠습니다~

오늘도 즐거운 개발하세요~ :)

 

* 참고자료

- https://fre2-dom.tistory.com/115