카카오 로그인(AOS)
개념
카카오 로그인은 OAuth 2.0 기반의 소셜 로그인 서비스이다. 카카오 로그인을 사용하면 사용자가 카카오톡 또는 카카오계정으로 손쉽게 서비스에 로그인할 수 있다. 서비스는 서비스 ID 및 비밀번호를 입력받고 검증하는 과정을 직접 구현하지 않고도 사용자에 대한 인증과 인가를 간편하고 안전하게 처리할 수 있다.
서비스는 카카오 로그인 완료 시 발급받은 토큰으로 회원 가입이나 정보 갱신에 필요한 사용자 정보를 제공받을 수 있다. 카카오 로그인의 추가 기능을 제공하는 카카오싱크 도입 시, 사용자에게 서비스 약관 동의와 카카오톡 채널 추가까지 한 화면에서 요청할 수 있다.
로그인 과정

구현
(1) 카카오 Developers 세팅
(2) 프로젝트 설정
(3) 서비스 구현
(4) 로그인 테스트
카카오 Developers 세팅
카카오 디벨로퍼 홈페이지 로그인 https://developers.kakao.com
각 항목들을 입력하고 앱을 추가한다.
Android App 등록
패키지명과 키 해시 값을 확인하는 방법은 아래에 기술
앱 키 확인
앱을 등록하면 앱 키를 확인 할 수 있다. 앱 키는 프로젝트 설정할 때 필요하니, 기억 해둔다.카카오 로그인 활성화 설정
Android 정보 확인하는 방법
패키지 명 - AndroidManifest.xml에서 확인키 해시 - 터미널 명령어로 확인하는 방법, Kakao SDK로 확인하는 방법이 있다.
터미널 명령어
Mac
(1) 디버그 키 해시 keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64 (2) 릴리즈 키 해시 keytool -exportcert -alias <RELEASE_KEY_ALIAS> -keystore <RELEASE_KEY_PATH> | openssl sha1 -binary | openssl base64Windows
(1) 디버그 키 해시 keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64 (2) 릴리즈 키 해시 keytool -exportcert -alias <RELEASE_KEY_ALIAS> -keystore <RELEASE_KEY_PATH> | openssl sha1 -binary | PATH_TO_OPENSSL_LIBRARY\bin\openssl base64
Kakao SDK
아래와 같이 코드를 추가 후, 로그를 출력하여 확인build.gradle (Project)
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/'}
build.gradle (Module)
implementation "com.kakao.sdk:v2-user:2.8.3"
MainActivity
import com.kakao.sdk.common.util.Utility var keyHash = Utility.getKeyHash(this) Log.d("keyHash", "keyHash : $keyHash")아래와 같이 로그로 확인 가능
프로젝트 설정
build.gradle (Project)
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/'}
추가build.gradle (Module)
implementation "com.kakao.sdk:v2-user:2.8.3"
추가AndroidManifest.xml
인터넷 권한 추가 -<uses-permission android:name="android.permission.INTERNET"/>
서비스 구현
SDK 초기화 (아래 전체 코드에 포함)
kakaoAppKey - 카카오 디벨로퍼에 있는 네이티브 앱 키를 넣어준다.private fun initialize() { getActivity()?.let { if (!mInitialized) { /** Kakao Login Module Initialize */ val kakaoAppKey = it.getString(R.string.social_login_info_kakao_app_key_twk) KakaoSdk.init(it.applicationContext, kakaoAppKey) // kakaoAppKey - 사용자의 네이티브 앱 키 사용 mInitialized = true } } }인가 코드 발급
카카오 인증 서버에서 전달해주는 인가 코드(Authorization Code)를 발급해 서비스 앱에 등록된 Redirect URI을 전달받아야 한다.
인가 코드 발급을 위해 AndroidManifest.xml에 다음 코드를 추가해준다.
여기서 android:schem에 들어가는 값은 "kakao + 네이티브 앱 키" 이다. 예를들어 네이티브 앱키가 '1234'면, 'kakao1234'가 들어간다.
<!-- Kakao Login --> <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" /> <!-- [카카오 로그인] --> <data android:host="oauth" android:scheme="@string/social_login_info_kakao_app_key_twk2" /> / </intent-filter> </activity>카카오 로그인 모듈 구현 (전체 코드)
여러 소셜로그인을 처리하는 SocialLoginController 클래스에 카카오 로그인 코드만 남겨두었다.class SocialLoginController (private val basicAct: AppCompatActivity) { var mInitialized = false var m_action: FlexAction? = null private fun initialize() { getActivity()?.let { if (!mInitialized) { /** Kakao Login Module Initialize */ val kakaoAppKey = it.getString(R.string.social_login_info_kakao_app_key_twk) KakaoSdk.init(it.applicationContext, kakaoAppKey) // kakaoAppKey - 사용자의 네이티브 앱 키 사용 mInitialized = true } } } /**====================================== Action =============================================*/ val socialLogin = FlexLambda.action { action, array: FlexArguments -> m_action = action withContext(Dispatchers.Main) { when(array[0]?.asString()){ "kakao" -> { startSocialLogin(DEFINES.SOCIAL_LOGIN.TYPE.kakao) } } } } fun startSocialLogin(loginType: DEFINES.SOCIAL_LOGIN.TYPE){ if(!mInitialized) initialize() when(loginType){ DEFINES.SOCIAL_LOGIN.TYPE.kakao -> { startKakaoLogin() } } } /** 카카오 */private fun startKakaoLogin(){ //카카오 유저의 id를 구해온다. fun getKakaoUserInfo(accessToken: String?){ UserApiClient.instance.me { user, error -> if (error != null) { onError(DEFINES.SOCIAL_LOGIN.TYPE.kakao,Error(error)) } else if (user != null) { onLoginCompleted(DEFINES.SOCIAL_LOGIN.TYPE.kakao,"${user.id}", accessToken,null) } } } //카카오 로그인 콜백 val onKakaoLoginCompleted: (OAuthToken?, Throwable?) -> Unit = { token, error -> if (error != null) { onError(DEFINES.SOCIAL_LOGIN.TYPE.kakao, Error(error)) } else if (token != null) { getKakaoUserInfo(token.accessToken) } } //로그인이 되어있는 경우 if (AuthApiClient.instance.hasToken()){ val accessToken = AuthApiClient.instance.tokenManagerProvider.manager.getToken()?.accessToken getKakaoUserInfo(accessToken) }else{ //카카오 로그인 시작 getActivity()?.let { if (UserApiClient.instance.isKakaoTalkLoginAvailable(it)) { UserApiClient.instance.loginWithKakaoTalk(it, callback = onKakaoLoginCompleted) } else { UserApiClient.instance.loginWithKakaoAccount(it, callback = onKakaoLoginCompleted) } } } } private fun onLoginCompleted(loginType: DEFINES.SOCIAL_LOGIN.TYPE, userId: String?, accessToken: String?, error: Error?){ Toast.makeText(App.context,"로그인 완료 userId : $userId , accessToken : $accessToken", Toast.LENGTH_SHORT).show() val returnData = JSONObject() returnData.put("userId", userId) returnData.put("accessToken", accessToken) val returnObj = Utils.returnJson(authValue = true, dataValue = returnData, msgValue = null) m_action?.promiseReturn(returnObj) } private fun onError(loginType : DEFINES.SOCIAL_LOGIN.TYPE, error : Error?){ Toast.makeText(App.context,"로그인 중 에러발생 ${error.toString()}", Toast.LENGTH_SHORT).show() val returnObj = Utils.returnJson(authValue = false, dataValue = null, msgValue = "로그인 중 에러발생 ${error.toString()}") m_action?.promiseReturn(returnObj) } }
로그인 테스트
참고 자료
[https://developers.kakao.com/docs/latest/ko/kakaologin/common#intro-kakaologin]https://developers.kakao.com/docs/latest/ko/kakaologin/common#intro-kakaologin