아래 링크에서 네이버 로그인을 사용하기 위한 프로젝트 정보를 등록해준 뒤 API키를 발급받는다.
https://developers.naver.com/apps

implementation 'com.navercorp.nid:oauth-jdk8:5.1.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
코루틴이 필요한 이유는 로그인한 유저 정보를 가져오는 메서드가 코루틴으로 실행되기 때문이다. 코루틴 의존성이 없다면 컴파일 에러가 발생한다.

<string name="social_login_info_naver_client_id">ID_KEY</string>
<string name="social_login_info_naver_client_secret">SECREY_KEY</string>
NaverIdLoginSDK.initialize(mContext,BuildConfig.NAVER_CLIENT_ID,BuildConfig.NAVER_CLIENT_SECRET,"LoginTest")
NaverIdLoginSDK.initialize() 메서드가 여러 번 실행돼도 기존에 저장된 access token)과 refresh token은 삭제되지 않는다.
기존에 저장된 접근 토큰과 갱신 토큰을 삭제하려면 NaverIdLoginSDK.logout() 메서드나 NidOAuthLogin().callDeleteTokenApi() 메서드를 호출한다.
fun initNaverLogin(view: View?) {
NaverIdLoginSDK.initialize(this@LoginActivity, getString(R.string.social_login_info_naver_client_id), getString(R.string.social_login_info_naver_client_secret), getString(R.string.app_name))
NaverIdLoginSDK.authenticate(this@LoginActivity, oAuthLoginCallback)
}
private val oAuthLoginCallback = object : OAuthLoginCallback {
override fun onSuccess() {
NidOAuthLogin().callProfileApi(object : NidProfileCallback<NidProfileResponse> {
override fun onSuccess(result: NidProfileResponse) {
val userName = result.profile!!.name.toString()
val userEmail = result.profile!!.email.toString()
val userNickname = result.profile!!.nickname.toString()
val userImage = result.profile!!.profileImage
Log.d("naver login data", userName)
Log.d("naver login data", userEmail)
Log.d("naver login data", userNickname)
Log.d("naver login data", userImage.toString())
requestToken(userEmail, userName, userNickname, userImage.toString(), "naver")
}
override fun onError(errorCode: Int, message: String) {
Log.e("login", message)
}
override fun onFailure(httpStatus: Int, message: String) {
Log.e("login", message)
}
})
}
}

implementation 'com.kakao.sdk:v2-user:2.10.0'
dependencyResolutionManagement {
...
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/'}
}
}
<application
...>
...
<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="kakao네이티브 앱 키" />
</intent-filter>
</activity>
</application>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
Log.d(TAG, "keyhash : ${Utility.getKeyHash(this)}")
}
KakaoSdk.init(this, NATIVE_APP_KEY)
fun initKakaoLogin(view: View?){
KakaoSdk.init(this@LoginActivity, "kakao api ke")
val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
if (error != null) {
Log.e("Kakao Login", "카카오계정으로 로그인 실패", error)
} else if (token != null) {
Log.i("Kakao Login", "카카오계정으로 로그인 성공 ${token.accessToken}")
UserApiClient.instance.me { user, error ->
if (error != null) {
Log.e("Kakao Login", "사용자 정보 요청 실패", error)
}
else if (user != null) {
val email = user.kakaoAccount?.email.toString()
}
}
}
}
// 카카오톡이 설치되어 있으면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인
if (UserApiClient.instance.isKakaoTalkLoginAvailable(this@LoginActivity)) {
UserApiClient.instance.loginWithKakaoTalk(this@LoginActivity) { token, error ->
if (error != null) {
Log.e("Kakao Login", "카카오톡으로 로그인 실패", error)
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
return@loginWithKakaoTalk
}
UserApiClient.instance.loginWithKakaoAccount(this@LoginActivity, callback = callback)
} else if (token != null) {
Log.i("Kakao Login", "카카오 로그인 성공 ${token.accessToken}")
UserApiClient.instance.me { user, error ->
if (error != null) {
Log.e("Kakao Login", "사용자 정보 요청 실패", error)
}
else if (user != null) {
val email = user.kakaoAccount?.email.toString()
}
}
}
}
} else {
UserApiClient.instance.loginWithKakaoAccount(this@LoginActivity, callback = callback)
}
}