Develop/Kotlin

[kotlin] 코틀린 Android Kakao Login(카카오 로그인) api 활용

JunJangE 2021. 7. 31. 15:04

이번에는 Kakao Developers에서 지원해주고 있는 카카오 로그인 api를 활용하여 로그인 기능을 구현해보도록 하겠다.

 

Kakao Developers

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

developers.kakao.com

요구 사양

시작하기 앞서 Android SDK를 사용하기 위한 최소 요구 사양을 확인하자.

  • Android Studio 3.6.1 이상
  • API 19: Android 4.4(KitKat) 이상
  • Java 8 이상

Gradle 설정

우선 프로젝트를 하나 생성하고 build.gradle(project) 파일에 Android SDK 레파지토리(Repository)를 설정한다.

다음 코드를 적고 우측 상단에 있는 'Sync Now'를 누른다.

maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }

build.gradle(Project)

다음으로 필요한 모듈을 추가하여 설정하고 우측 상단에 있는 'Sync Now'를 누른다.

여기서는 카카오 로그인 모듈만 추가한다.

implementation "com.kakao.sdk:v2-user:2.0.1"

build.gradle(Module)

카카오 api를 통해 카카오 서버와 통신하기 위해 앱에 인터넷 사용 권한을 설정한다.

mainfests -> AndroidMainfest.xml에서 다음 코드를 적는다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sample">

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

    <application
    android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
    ...

키 해시 구하기

MainActivity에서 다음 코드를 작성해 키 해시를 구한다.

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.kakao.sdk.common.util.Utility

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val keyHash = Utility.getKeyHash(this)
        Log.d("Hash", keyHash)

    }
}

코드를 적고 실행시키면 다음 사진과 같이 키 해시를 구할 수 있다.

키 해시

이제 키 해시를 복사하여 android 플랫폼 등록에 사용한다.

Kakao Developers에 애플리케이션 추가

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

위 링크에 들어가 카카오 계정으로 로그인 후 애플리케이션 추가하기를 눌러 카카오 로그인 api를 사용할 애플리케이션을 등록한다.

앱 이름은 자신이 원하는 이름으로 하고 회사 이름은 자신의 이름으로 설정하여 저장한다.

성공적으로 생성을 했으면 '플랫폼'에 들어가 Android 플랫폼 등록을 누른다.

내 애플리케이션

Android 플랫폼 등록을 할 때 패키지 명과 키 해시가 필요하다.

패키지 명

패키지 명은 위 사진처럼 패키지 옆에 쓰여있는 것을 복사하여 가져오면 되고 키 해시는 위에서 로그로 찾아낸 키 해시를 복사하여 붙였으고 저장하면 된다.

Android 플랫폼 등록

GlobalApplication 생성

Kakao SDK를 사용하기 위해서 Native App Key로 초기화를 해야 한다.

GlobalApplication이란 이름으로 된 코틀린 class를 하나 생성한다.

생성된 class에 다음 코드를 작성하고 appKey에 네이티브 앱 키를 작성한다.

import android.app.Application
import com.kakao.sdk.common.KakaoSdk

class GlobalApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        KakaoSdk.init(this, "네이티브 앱 키")
    }
}

네이티브 앱 키는 '요약정보' 탭에서 확인할 수 있다.

네이티브 앱 키

 

AndroidManifest.xml 설정

GlobalApplication을 생성했으면 Mainfset에서 GlobalApplication 클래스가 사용될 수 있도록 한다.

android:name=".GlobalApplication"

위 코드를 application 태그 안에 작성하여 애플리케이션 프로세스가 시작될 때,  애플리케이션의 다른 컴포넌트보다 먼저 실행되게 한다.

AndroidManifest.xml

다음으로 로그인 창이 되는 액티비티를 추가한다.

  <activity android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity">
            <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네이티브 앱 키" />
            </intent-filter>
        </activity>

네이티브 앱 키 부분에는 위에 사용했던 네이티브 앱 키를 복붙 하면 된다.

형식은 kakao + 네이티브 앱 키 를 작성해야 한다. kakao를 작성하지 않고 네이티브 앱 키만 작성할 경우 카카오 로그인 창으로 이동이 안될 수 있다.

AndroidManifest.xml

카카오 로그인 버튼 생성

 

Kakao Developers

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

developers.kakao.com

위 링크에서 버튼 이미지를 다운로드할 수 있다.

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">

    <ImageButton
        android:id="@+id/kakao_login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/kakao_login_medium_wide"
        android:background="@android:color/transparent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="40dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity에 로그인 코드를 작성한다.

주석을 잘 확인하면서 코드를 작성하자.

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ImageButton
import android.widget.Toast
import com.kakao.sdk.auth.LoginClient
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.util.Utility
import com.kakao.sdk.common.model.AuthErrorCause.*
import com.kakao.sdk.user.UserApiClient

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 로그인 정보 확인
        UserApiClient.instance.accessTokenInfo { tokenInfo, error ->
            if (error != null) {
                Toast.makeText(this, "토큰 정보 보기 실패", Toast.LENGTH_SHORT).show()
            }
            else if (tokenInfo != null) {
                Toast.makeText(this, "토큰 정보 보기 성공", Toast.LENGTH_SHORT).show()
                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                finish()
            }
        }

        
//        val keyHash = Utility.getKeyHash(this)
//        Log.d("Hash", keyHash)


        val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
            if (error != null) {
                when {
                    error.toString() == AccessDenied.toString() -> {
                        Toast.makeText(this, "접근이 거부 됨(동의 취소)", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == InvalidClient.toString() -> {
                        Toast.makeText(this, "유효하지 않은 앱", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == InvalidGrant.toString() -> {
                        Toast.makeText(this, "인증 수단이 유효하지 않아 인증할 수 없는 상태", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == InvalidRequest.toString() -> {
                        Toast.makeText(this, "요청 파라미터 오류", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == InvalidScope.toString() -> {
                        Toast.makeText(this, "유효하지 않은 scope ID", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == Misconfigured.toString() -> {
                        Toast.makeText(this, "설정이 올바르지 않음(android key hash)", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == ServerError.toString() -> {
                        Toast.makeText(this, "서버 내부 에러", Toast.LENGTH_SHORT).show()
                    }
                    error.toString() == Unauthorized.toString() -> {
                        Toast.makeText(this, "앱이 요청 권한이 없음", Toast.LENGTH_SHORT).show()
                    }
                    else -> { // Unknown
                        Toast.makeText(this, "기타 에러", Toast.LENGTH_SHORT).show()
                    }
                }
            }
            else if (token != null) {
                Toast.makeText(this, "로그인에 성공하였습니다.", Toast.LENGTH_SHORT).show()
                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                finish()
            }
        }


        val kakao_login_button = findViewById<ImageButton>(R.id.kakao_login_button) // 로그인 버튼

        kakao_login_button.setOnClickListener {
            if(LoginClient.instance.isKakaoTalkLoginAvailable(this)){
                LoginClient.instance.loginWithKakaoTalk(this, callback = callback)


            }else{
                LoginClient.instance.loginWithKakaoAccount(this, callback = callback)
            }
        }
    }

}

이때 로그인 후 이동해야 하는 액티비티를 하나 만들어야 한다.

자신이 원하는 이름으로 액티비티를 하나 만들고 그 액티비티와 연결시킨다.

로그아웃 버튼, 회원 탈퇴 버튼 생성

로그인을 하면 로그아웃도 필요하고 회원 탈퇴 기능도 필요하다.

로그인 후 이동되는 액티비티에 로그아웃 버튼과 회원 탈퇴 버튼을 만들자.

우선 이동되는 액티비티 레이아웃에 다음 코드를 작성한다.

<?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=".SecondActivity">


    <Button
        android:id="@+id/kakao_logout_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="로그아웃"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/kakao_unlink_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <Button
        android:id="@+id/kakao_unlink_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="회원 탈퇴"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

그리고 activity에는 다음 코드를 작성한다.

import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import com.kakao.sdk.user.UserApiClient

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val kakao_logout_button = findViewById<Button>(R.id.kakao_logout_button) // 로그인 버튼

        kakao_logout_button.setOnClickListener {
            UserApiClient.instance.logout { error ->
                if (error != null) {
                    Toast.makeText(this, "로그아웃 실패 $error", Toast.LENGTH_SHORT).show()
                }else {
                    Toast.makeText(this, "로그아웃 성공", Toast.LENGTH_SHORT).show()
                }
                val intent = Intent(this, MainActivity::class.java)
                startActivity(intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP))
                finish()
            }
        }

        val kakao_unlink_button = findViewById<Button>(R.id.kakao_unlink_button) // 로그인 버튼

        kakao_unlink_button.setOnClickListener {
            UserApiClient.instance.unlink { error ->
                if (error != null) {
                    Toast.makeText(this, "회원 탈퇴 실패 $error", Toast.LENGTH_SHORT).show()
                }else {
                    Toast.makeText(this, "회원 탈퇴 성공", Toast.LENGTH_SHORT).show()
                    val intent = Intent(this, MainActivity::class.java)
                    startActivity(intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP))
                    finish()
                }
            }
        }
    }

}

코드를 작성하고 실행하기 전에 카카오 로그인 설정을 활성화시켜줘야 정상적으로 실행시킬 수 있다.

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

위 링크로 들어가 카카오 로그인 상태를 ON으로 바꾼다.

사용자 정보 조회

로그인 과정에서 사용자가 동의한 정보를 불러올 수 있다.

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

위 링크를 통해 아래 창을 들어가서 자신이 필요한 정보를 동의를 구해 불러온다.

예제에서는 닉네임을 예시로 하여 불러오자.

내 애플리케이션 -> 제품 설정 -> 카카오 로그인 -> 동의 항목
동의 항목 설정

동의 항목 설정은 위 창과 같이 설정하면 된다.

이제 정보를 받아올 액티비티와 레이아웃을 수정해야 하는데 로그인 후 실행되는 액티비티를 수정하도록 하자.

다음 액티비티 코드를 onCreate에 작성한다. 

        val nickname = findViewById<TextView>(R.id.nickname) // 로그인 버튼


        UserApiClient.instance.me { user, error ->
            nickname.text = "닉네임: ${user?.kakaoAccount?.profile?.nickname}"

        }

다음 레이아웃 코드는 버튼 위에 추가하면 된다.

    <TextView
        android:id="@+id/nickname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="닉네임: "
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

위 코드를 모두 작성 후 실행하면 다음 결과 사진과 같이 카카오톡 닉네임 정보를 불러올 수 있다.

<결과 사진>

위 모든 코드를 실행하는 영상은 다음과 같다.

<실행 영상>

참고

 

Kakao Developers

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

developers.kakao.com

github

 

GitHub - junjange/KakaoApi-Learning: 카카오 api 학습

카카오 api 학습. Contribute to junjange/KakaoApi-Learning development by creating an account on GitHub.

github.com