안녕하세요~ 챠니입니다! :)
오늘은 네이버 아이디 로그인연동에 대해서 알아보겠습니다.
줄여서 "네아로"라고도 불리는데요 어렵지 않으니 하나씩 천천히 따라오시면 되겠습니다 :)
Naver Developers 설정
● Naver Developers 접속
https://developers.naver.com/apps
● 우측상단 "Application 등록" 클릭
● 애플리케이션 이름, 사용 API(네이버 로그인) 선택
● 사용 API를 선택, 로그인 오픈 API 서비스 환경(안드로이드) 선택
● 다운로드 URL(앱 다운로드 가능한 URL, 없으면 https://www.naver.com 이렇게 막 입력해도 가능)
안드로이드 앱 패키지 이름(안드로이드 프로젝트 - AndroidManifest.xml의 pakageName 입력)
모두 입력했으면 마지막 "등록하기" 클릭
● Client ID, Client Secret 값을 잘 적어둡니다.
(안드로이드 프로젝트에서 사용)
Android Proejct
네이버 개발가이드: https://developers.naver.com/docs/login/android/android.md#android
안드로이드 애플리케이션을 생성 및 다음 코드들을 추가합니다.
● build.gradle(:app)
//네이버 로그인
implementation 'com.navercorp.nid:oauth-jdk8:5.1.0' // jdk 8
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
● strings.xml
<string name="social_login_info_naver_client_id">ID_KEY</string>
<string name="social_login_info_naver_client_secret">SECREY_KEY</string>
<string name="social_login_info_naver_client_name">네이버아이디 로그인</string>
● MainActivity.kt
NaverIdLoginSDK.initialize 또는 NaverIdLoginSDK.authenticate 에서
Activity -> this (Activity / this로 표기)
Fragment -> requireActivity() or Context가 아닌 Activity로 표기
/** MainActivity.kt */
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
/** Naver Login Module Initialize */
val naverClientId = getString(R.string.social_login_info_naver_client_id)
val naverClientSecret = getString(R.string.social_login_info_naver_client_secret)
val naverClientName = getString(R.string.social_login_info_naver_client_name)
NaverIdLoginSDK.initialize(this, naverClientId, naverClientSecret , naverClientName)
setLayoutState(false)
binding.tvNaverLogin.setOnClickListener {
startNaverLogin()
}
binding.tvNaverLogout.setOnClickListener {
startNaverLogout()
}
binding.tvNaverDeleteToken.setOnClickListener {
startNaverDeleteToken()
}
}
/**
* 로그인
* authenticate() 메서드를 이용한 로그인 */
private fun startNaverLogin(){
var naverToken :String? = ""
val profileCallback = object : NidProfileCallback<NidProfileResponse> {
override fun onSuccess(response: NidProfileResponse) {
val userId = response.profile?.id
binding.tvResult.text = "id: ${userId} \ntoken: ${naverToken}"
setLayoutState(true)
Toast.makeText(this@MainActivity, "네이버 아이디 로그인 성공!", Toast.LENGTH_SHORT).show()
}
override fun onFailure(httpStatus: Int, message: String) {
val errorCode = NaverIdLoginSDK.getLastErrorCode().code
val errorDescription = NaverIdLoginSDK.getLastErrorDescription()
Toast.makeText(this@MainActivity, "errorCode: ${errorCode}\n" +
"errorDescription: ${errorDescription}", Toast.LENGTH_SHORT).show()
}
override fun onError(errorCode: Int, message: String) {
onFailure(errorCode, message)
}
}
/** OAuthLoginCallback을 authenticate() 메서드 호출 시 파라미터로 전달하거나 NidOAuthLoginButton 객체에 등록하면 인증이 종료되는 것을 확인할 수 있습니다. */
val oauthLoginCallback = object : OAuthLoginCallback {
override fun onSuccess() {
// 네이버 로그인 인증이 성공했을 때 수행할 코드 추가
naverToken = NaverIdLoginSDK.getAccessToken()
// var naverRefreshToken = NaverIdLoginSDK.getRefreshToken()
// var naverExpiresAt = NaverIdLoginSDK.getExpiresAt().toString()
// var naverTokenType = NaverIdLoginSDK.getTokenType()
// var naverState = NaverIdLoginSDK.getState().toString()
//로그인 유저 정보 가져오기
NidOAuthLogin().callProfileApi(profileCallback)
}
override fun onFailure(httpStatus: Int, message: String) {
val errorCode = NaverIdLoginSDK.getLastErrorCode().code
val errorDescription = NaverIdLoginSDK.getLastErrorDescription()
Toast.makeText(this@MainActivity, "errorCode: ${errorCode}\n" +
"errorDescription: ${errorDescription}", Toast.LENGTH_SHORT).show()
}
override fun onError(errorCode: Int, message: String) {
onFailure(errorCode, message)
}
}
NaverIdLoginSDK.authenticate(this, oauthLoginCallback)
}
/**
* 로그아웃
* 애플리케이션에서 로그아웃할 때는 다음과 같이 NaverIdLoginSDK.logout() 메서드를 호출합니다. */
private fun startNaverLogout(){
NaverIdLoginSDK.logout()
setLayoutState(false)
Toast.makeText(this@MainActivity, "네이버 아이디 로그아웃 성공!", Toast.LENGTH_SHORT).show()
}
/**
* 연동해제
* 네이버 아이디와 애플리케이션의 연동을 해제하는 기능은 다음과 같이 NidOAuthLogin().callDeleteTokenApi() 메서드로 구현합니다.
연동을 해제하면 클라이언트에 저장된 토큰과 서버에 저장된 토큰이 모두 삭제됩니다.
*/
private fun startNaverDeleteToken(){
NidOAuthLogin().callDeleteTokenApi(this, object : OAuthLoginCallback {
override fun onSuccess() {
//서버에서 토큰 삭제에 성공한 상태입니다.
setLayoutState(false)
Toast.makeText(this@MainActivity, "네이버 아이디 토큰삭제 성공!", Toast.LENGTH_SHORT).show()
}
override fun onFailure(httpStatus: Int, message: String) {
// 서버에서 토큰 삭제에 실패했어도 클라이언트에 있는 토큰은 삭제되어 로그아웃된 상태입니다.
// 클라이언트에 토큰 정보가 없기 때문에 추가로 처리할 수 있는 작업은 없습니다.
Log.d("naver", "errorCode: ${NaverIdLoginSDK.getLastErrorCode().code}")
Log.d("naver", "errorDesc: ${NaverIdLoginSDK.getLastErrorDescription()}")
}
override fun onError(errorCode: Int, message: String) {
// 서버에서 토큰 삭제에 실패했어도 클라이언트에 있는 토큰은 삭제되어 로그아웃된 상태입니다.
// 클라이언트에 토큰 정보가 없기 때문에 추가로 처리할 수 있는 작업은 없습니다.
onFailure(errorCode, message)
}
})
}
private fun setLayoutState(login: Boolean){
if(login){
binding.tvNaverLogin.visibility = View.GONE
binding.tvNaverLogout.visibility = View.VISIBLE
binding.tvNaverDeleteToken.visibility = View.VISIBLE
}else{
binding.tvNaverLogin.visibility = View.VISIBLE
binding.tvNaverLogout.visibility = View.GONE
binding.tvNaverDeleteToken.visibility = View.GONE
binding.tvResult.text = ""
}
}
}
● 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_naver_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#2DB400"
android:padding="20dp"
android:text="Naver Login"
android:textColor="#FFFFFF"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tv_naver_logout"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_naver_logout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#2DB400"
android:padding="20dp"
android:text="Naver Logout"
android:textColor="#FFFFFF"
android:visibility="gone"
app:layout_constraintLeft_toRightOf="@+id/tv_naver_login"
app:layout_constraintRight_toLeftOf="@+id/tv_naver_delete_token"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_naver_delete_token"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#2DB400"
android:padding="20dp"
android:text="Naver Delete Token"
android:textColor="#FFFFFF"
android:visibility="gone"
app:layout_constraintLeft_toRightOf="@+id/tv_naver_logout"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="id, token: "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cl_login" />
</androidx.constraintlayout.widget.ConstraintLayout>
결과
전체 소스코드
[소스코드]
네이버 아이디 로그인: https://github.com/younminchan/kotlin-sns-samples/tree/main/kotlin-naver-login
질문 또는 궁굼한 부분은 댓글을 남겨주세요! 친절하게 답변드리겠습니다!
응원의 댓글은 저에게 큰 힘이 된답니다! :)
즐거운 하루되세요!
깃허브 보러 놀러오세요 👇 (맞팔환영)
https://github.com/younminchan