본문 바로가기

안드로이드

[Android] 카카오 로그인(v2) 구현 가이드

개요

안드로이드 애플리케이션에서 카카오 로그인(v2)을 구현하는 방법을 소개한다. 기존 Legacy 구현 방법과 다소 차이가 존재한다.

 

1. Kakao Developers 설정

  1. Application 등록
  2. kakao login 활성화
  3. Android 플랫폼 등록(키해시, 패키지명 등)
  4. kakao login에서 Redirect URI 설정(안드로이드의 경우 임의의 URI를 설정하면 된다.)

2. 종속성 추가 및 manifest 수정

build.gradle(project)

allprojects {
    repositories {
        ...
        maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/'}
    }
}

build.gradle(app)

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

 

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{YOUR NATIVE APP KEY}" />
            </intent-filter>
</activity>

 

3. 로그인 구현

SplashActivity에서 UserApiClient를 통해 로그인되어 있는 유저 정보 획득을 시도한 뒤, 유저 정보가 없으면 에러가 존재하여 로그인을 시도한다. 유저 정보가 있을 경우 다음 액티비티로 이동한다.

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
		
        //로그인되어 있는 유저 정보 획득
        UserApiClient.instance.me { user, error ->
        	//에러가 존재할 경우(로그인 정보 없음) -> 로그인 시도
            if (error != null) {
                LoginClient.instance.run {
                    if(isKakaoTalkLoginAvailable(this@SplashActivity))
                        loginWithKakaoTalk(this@SplashActivity,callback = callback)
                    else
                        loginWithKakaoAccount(this@SplashActivity,callback = callback)
                }
            }
            //유저 정보가 존재할 경우 ->  kakaoId로 개인 API 서버에서 유저 정보 획득
            else if (user != null) {
                startMainActivity(user);
            }
        }

    }

	//로그인 시도 후 사용하는 Callback
    val callback:(OAuthToken?,Throwable?) -> Unit = { token, error ->
    	//로그인 실패
        if (error != null) {
            Log.e("LOGIN_ERORR", error.message)
        }
        //로그인 성공
        else {
            UserApiClient.instance.accessTokenInfo { tokenInfo, _ ->
                startMainActivity(user);
            }
        }
    }


    private fun startMainActivity(user: User){...}
}

 

다음은 앱을 위한 API 서버가 따로 존재하여, 로그인에 성공할 시 유저의 kakaoId로 API 서버에서 해당 유저의 상세 정보를 조회하여 가져온 뒤 다음 액티비티로 이동하는 예시이다.

class SplashActivity : AppCompatActivity() {
    private lateinit var repository : Repository
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        repository = Repository(application)
		
        //로그인되어 있는 유저 정보 획득
        UserApiClient.instance.me { user, error ->
        	//에러가 존재할 경우(로그인 정보 없음) -> 로그인 시도
            if (error != null) {
                LoginClient.instance.run {
                    if(isKakaoTalkLoginAvailable(this@SplashActivity))
                        loginWithKakaoTalk(this@SplashActivity,callback = callback)
                    else
                        loginWithKakaoAccount(this@SplashActivity,callback = callback)
                }
            }
            //유저 정보가 존재할 경우 ->  kakaoId로 개인 API 서버에서 유저 정보 획득
            else if (user != null) {
                findOrCreateUser(user.id.toInt())
            }
        }

    }

	//로그인 시도 후 사용하는 Callback
    val callback:(OAuthToken?,Throwable?) -> Unit = { token, error ->
        if (error != null) {
            Log.e("LOGIN_ERORR", error.message)
        } else {
            UserApiClient.instance.accessTokenInfo { tokenInfo, _ ->
                findOrCreateUser(tokenInfo!!.id.toInt())
            }
        }
    }

    private fun findOrCreateUser(kakaoId: Int){
        repository.postUser(User(kakaoId)) //kakaoId
            .subscribe({
                BaseApplication.instance!!.userId = it.id!!
                if (it.name!!.isBlank())
                    startSetUserActivity()
                else
                    startMainActivity(it)
            }, {
                Log.d("LOGIN_ACTIVITY", it.toString())
            })
    }

    private fun startMainActivity(user: User){...}

    private fun startSetUserActivity(){...}

}