이번에는 Kakao Developers에서 지원해주고 있는 카카오 로그인 api를 활용하여 로그인 기능을 구현해보도록 하겠다.
요구 사양
시작하기 앞서 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/' }
다음으로 필요한 모듈을 추가하여 설정하고 우측 상단에 있는 'Sync Now'를 누른다.
여기서는 카카오 로그인 모듈만 추가한다.
implementation "com.kakao.sdk:v2-user:2.0.1"
카카오 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에 애플리케이션 추가
위 링크에 들어가 카카오 계정으로 로그인 후 애플리케이션 추가하기를 눌러 카카오 로그인 api를 사용할 애플리케이션을 등록한다.
앱 이름은 자신이 원하는 이름으로 하고 회사 이름은 자신의 이름으로 설정하여 저장한다.
성공적으로 생성을 했으면 '플랫폼'에 들어가 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 태그 안에 작성하여 애플리케이션 프로세스가 시작될 때, 애플리케이션의 다른 컴포넌트보다 먼저 실행되게 한다.
다음으로 로그인 창이 되는 액티비티를 추가한다.
<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를 작성하지 않고 네이티브 앱 키만 작성할 경우 카카오 로그인 창으로 이동이 안될 수 있다.
카카오 로그인 버튼 생성
위 링크에서 버튼 이미지를 다운로드할 수 있다.
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()
}
}
}
}
}
코드를 작성하고 실행하기 전에 카카오 로그인 설정을 활성화시켜줘야 정상적으로 실행시킬 수 있다.
위 링크로 들어가 카카오 로그인 상태를 ON으로 바꾼다.
사용자 정보 조회
로그인 과정에서 사용자가 동의한 정보를 불러올 수 있다.
위 링크를 통해 아래 창을 들어가서 자신이 필요한 정보를 동의를 구해 불러온다.
예제에서는 닉네임을 예시로 하여 불러오자.
동의 항목 설정은 위 창과 같이 설정하면 된다.
이제 정보를 받아올 액티비티와 레이아웃을 수정해야 하는데 로그인 후 실행되는 액티비티를 수정하도록 하자.
다음 액티비티 코드를 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" />
위 코드를 모두 작성 후 실행하면 다음 결과 사진과 같이 카카오톡 닉네임 정보를 불러올 수 있다.
위 모든 코드를 실행하는 영상은 다음과 같다.
참고
github
'Develop > Kotlin' 카테고리의 다른 글
[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(JSON 문서) (0) | 2021.08.08 |
---|---|
[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(XML 문서) (3) | 2021.08.04 |
[AWS] 아마존 웹 서비스 코틀린 Android + Amazon Cognito (0) | 2021.07.29 |
[kotlin] 코틀린 Android Bottom Navigation View 생성 (0) | 2021.07.28 |
[kotlin] 코틀린 Android Bottom Navigation Activity 뒤로가기시 앱 종료 (0) | 2021.07.24 |