[Android / Kotlin] SNS 로그인 api | Kakao (2)

Happy Jiwon·2023년 1월 25일
0

Kotlin

목록 보기
2/6
post-thumbnail

시작하기 전..

로그인 구현 방법을 소개할 예정이다!!

카카오 로그인 구현에 필요한 로그인 버튼 이미지는 [도구] > 리소스 다운로드에서 제공해준다.


✅ 구현 방식

Android SDK를 사용한 카카오 로그인 구현 방법은 두 가지로 나뉜다.

구현 방법메서드설명
카카오톡으로 로그인(권장)loginWithKakaoTalk()카카오톡에 연결된 카카오계정 및 인증 정보를 사용
사용자가 카카오계정 정보를 직접 입력하지 않아도 간편하게 로그인 가능
카카오계정으로 로그인loginWithKakaoAccount()기본 웹 브라우저(Default Browser)를 통해 카카오계정 정보를 입력하고 로그인
사용자가 카카오계정 정보를 직접 입력하는 단계를 거침
사용자가 여러 개의 카카오계정을 사용하는 서비스, 카카오톡 미설치 또는 미지원 디바이스에서 사용

✅ Redirect URI 설정

카카오 로그인 기능을 구현하기 위해서는 리다이렉션(Redirection)을 통해 인가 코드를 받아야 한다.
이를 위해 AndroidManifest.xml에 액티비티(Activity) 아래와 같은 설정이 필요하다.

<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" -->
        <data android:host="oauth"
                android:scheme="kakao${NATIVE_APP_KEY}" />
    </intent-filter>
</activity>
  • 새로운 액티비티를 추가하고, name 요소의 값은 "com.kakao.sdk.auth.AuthCodeHandlerActivity"로 입력
  • Android 12(API 31) 이상을 타깃으로 하는 앱인 경우, exported 요소를 반드시 "true"로 선언
  • 해당 액티비티 하위에 <intent-filter> 요소를 추가하고, host와 scheme 요소 값으로 카카오 로그인을 위한 Redirect URI를 설정한다.
  • scheme 속성의 값은 "kakao${NATIVE_APP_KEY}" 형식으로 입력한다.
    scheme 값은 네이티브 앱 키 앞에 'kakao'만 붙인 것이다.

카카오 인증 서버가 지정된 Redirect URI로 인가 코드를 보내면, Android SDK가 인가 코드를 받아 토큰 받기를 요청합니다. 자세한 과정은 이해하기를 참고합니다.


✅ 카카오 로그인

카카오 로그인 이미지 버튼

시작하기 전에 다운로드 받았던 로그인 버튼 이미지를 레이아웃 파일에 추가하여 화면 중앙에 버튼을 배치해볼 예정이다.

<androidx.constraintlayout.widget.ConstraintLayout>
<ImageButton
	android:background="@drawable/kakao_login_medium_narrow"
	android:id="@+id/btn_kakao"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	app:layout_constraintTop_toTopOf="parent"
	app:layout_constraintStart_toStartOf="parent"
	app:layout_constraintBottom_toBottomOf="parent"
	app:layout_constraintEnd_toEndOf="parent" />
  ...
</androidx.constraintlayout.widget.ConstraintLayout>

  • ConstraintLayout을 사용하여 중앙에 배치

카카오 로그인 성공 화면

로그인이 성공되면 화면을 이동하여 '로그인 성공'과 '로그아웃 버튼'을 배치해보겠다.

<androidx.constraintlayout.widget.ConstraintLayout>
  ...

    <TextView
        android:id="@+id/tv_login"
        android:text="로그인 성공!!"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
   <Button
        android:id="@+id/btn_logout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="로그아웃"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


카카오톡으로 로그인하기

UserApiClientloginWithKakaoTalk()을 호출하기 전 isKakaoTalkLoginAvailable()로 카카오톡 실행 가능 여부를 확인할 것을 권장하기 때문에 아래와 같이 입력한다.

btnKakaoLogin.setOnClickListener {
    // kakao 실행 가능 여부
    if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) {
        // 가능하다면 카카오톡으로 로그인하기
        UserApiClient.instance.loginWithKakaoTalk(this) { token, error ->
            if (error != null) {
                Toast.makeText(this, "카카오톡으로 로그인 실패!", Toast.LENGTH_SHORT).show()
                Log.e("test", "카카오톡으로 로그인 실패! " + error.message)

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


            } else if (token != null) {
                Toast.makeText(this, "카카오톡으로 로그인 성공!", Toast.LENGTH_SHORT).show()
                Log.d("test", "카카오톡으로 로그인 성공! " + token.accessToken)

                val intent = Intent(this, LoginSuccessActivity::class.java)
                startActivity(intent)
                finish()
            }

            // kakao로 로그인 하지 못 할 경우 계정으로 로그인 시도
            UserApiClient.instance.loginWithKakaoAccount(this, callback = callback)
        }
    } else {
        UserApiClient.instance.loginWithKakaoAccount(this, callback = callback)
    }
}

callback은 이메일 로그인의 callback인데, 두 군데에서 로그인이 사용되기 때문에 따로 callback을 변수로 만들어 코드를 간결하게 만들었다.

val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
    if (error != null) {
        Toast.makeText(this, "카카오 계정으로 로그인 실패!", Toast.LENGTH_SHORT).show()
        Log.e("test", "카카오 계정으로 로그인 실패! " + error.message)

    } else if (token != null) {
        Toast.makeText(this, "카카오 계정으로 로그인 성공!", Toast.LENGTH_SHORT).show()
        Log.d("test", "카카오 계정으로 로그인 성공! " + token.accessToken)

        val intent = Intent(this, LoginSuccessActivity::class.java)
        startActivity(intent)
        finish()
    }
}

로그인이 성공되면 아래와 같은 화면이 나타난다. 후후....


✅ 카카오 로그아웃

로그아웃

사용자 액세스 토큰과 리프레시 토큰을 모두 만료시켜, 더 이상 해당 사용자 정보로 카카오 API를 호출할 수 없도록 하는 것이다.
UserApiClientlogout()을 호출해 로그아웃을 요청할 수 있다.

로그아웃은 요청 성공 여부와 관계없이 토큰을 삭제 처리한다.

// 성공 여부와 관계 없이 토큰 삭제.
UserApiClient.instance.logout { error ->
    if (error != null) {
        Log.e("test", "로그아웃 실패. SDK에서 토큰 삭제됨", error)
    } else {
        Log.e("test", "로그아웃 실패. SDK에서 토큰 삭제됨", error)
    }
}

연결끊기

카카오 플랫폼 안에서 앱과 사용자 카카오계정의 연결 상태를 해제한다. UserApiClientunlink()를 호출합니다.

연결이 끊어지면 기존의 토큰은 더 이상 사용할 수 없으므로, 연결 끊기 요청 성공 시 로그아웃 처리가 함께 이뤄져 토큰이 삭제된다.

UserApiClient.instance.unlink { error ->
    if (error != null) {
        Log.e("test", "연결 끊기 실패", error)
    } else {
        Log.i("test", "연결 끊기 성공. SDK에서 토큰 삭제 됨")
    }
}

로그아웃 vs 연결끊기
앱 시작 시 첫 로그인할 때 사용자 정보 동의를 하는데,
이때 연결끊기를 하면 사용자 정보 동의 창이 다시 뜨게 된다.
즉, 앱과 사용자 계정의 연결을 끊어주는 의미이다.


카카오 로그인 끗

profile
공부가 조은 안드로이드 개발자

0개의 댓글