코딩하는 일용직 노동자

안드로이드 네이버 아이디 로그인 구현하기 본문

안드로이드

안드로이드 네이버 아이디 로그인 구현하기

bacass 2022. 8. 24. 11:38
안드로이드 네이버 아이디 로그인을 구현해보겠습니다.

우선 네이버 개발자센터에서 앱을 추가해줍니다.
 
 
 
앱의 이름과 패키지명, URL등을 등록하면 아래의 정보들을 이용할 수 있습니다.

OAUTH_CLIENT_ID: 애플리케이션 등록 후 발급받은 클라이언트 아이디
OAUTH_CLIENT_SECRET: 애플리케이션 등록 후 발급받은 클라이언트 시크릿
OAUTH_CLIENT_NAME: 네이버 앱의 로그인 화면에 표시할 애플리케이션 이름. 모바일 웹의 로그인 화면을 사용할 때는 서버에 저장된 애플리케이션 이름이 표시됩니다.


적용할 안드로이드 프로젝트의 gradle에 네이버 아이디 로그인 라이브러리를 추가해줍니다.

implementation 'com.navercorp.nid:oauth:5.1.1' // jdk 11
implementation 'com.navercorp.nid:oauth-jdk8:5.1.1' // jdk 8

 
strings.xml 파일에 네이버 개발자센터에서 앱을 등록후 생성된 Client ID 와 Client Secret정보들을 추가해줍니다.
    <!--login naver-->
    <string name="naver_client_id">3XXXXXXXXXXXXXXXXXXXX</string>
    <string name="naver_client_secret">XxXxXxXxXxXx</string>
    <string name="naver_client_name">NaverLoginExam</string>
Manifest.xml 파일에 인터넷 퍼미션도 추가해줍니다.
<uses-permission android:name="android.permission.INTERNET" />​


네이버 로그인은 NidOAuthLoginButton 를 이용해서 로그인하는 방법과
authenticate() 메서드를 이용한 로그인이 있습니다.

 
다음은 NaverIdLoginSDK.authenticate() 메서드를 이용한 로그인을 구현한 예제입니다.

<?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">

    <Button
        android:id="@+id/btnLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Login"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnLogout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Logout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnLogin" />

</androidx.constraintlayout.widget.ConstraintLayout>​

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.navercorp.nid.NaverIdLoginSDK
import com.navercorp.nid.NaverIdLoginSDK.authenticate
import com.navercorp.nid.NaverIdLoginSDK.getAccessToken
import com.navercorp.nid.NaverIdLoginSDK.getLastErrorCode
import com.navercorp.nid.NaverIdLoginSDK.getLastErrorDescription
import com.navercorp.nid.NaverIdLoginSDK.initialize
import com.navercorp.nid.oauth.NidOAuthLogin
import com.navercorp.nid.oauth.OAuthLoginCallback
import com.navercorp.nid.profile.NidProfileCallback
import com.navercorp.nid.profile.data.NidProfileResponse

class MainActivity : AppCompatActivity(), OAuthLoginCallback {

    private val TAG = "MainActivity"

    private var btnLogin: Button? = null
    private var btnLogout: Button? = null
    private var naverToken: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btnLogin = findViewById<View>(R.id.btnLogin) as Button
        btnLogout = findViewById<View>(R.id.btnLogout) as Button
        btnLogin!!.setOnClickListener { loginNaver() }
        btnLogout!!.setOnClickListener { logoutNaver() }
    }

    private fun loginNaver() {
        initialize(
            this,
            getString(R.string.naver_client_id),
            getString(R.string.naver_client_secret),
            getString(R.string.naver_client_name)
        )
        authenticate(this, this)
    }

    override fun onSuccess() {
        // 네이버 로그인 인증이 성공했을 때
        Toast.makeText(this, "naver onSuccess", Toast.LENGTH_SHORT).show()
        naverToken = getAccessToken()

        //로그인 유저 정보 가져오기
        NidOAuthLogin().callProfileApi(nidProfileCallback)
    }

    override fun onError(i: Int, s: String) {
//        Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
    }

    override fun onFailure(i: Int, s: String) {
        val errorCode = getLastErrorCode().code
        val errorDescription = getLastErrorDescription()
        //Toast.makeText(mContext, "errorCode:" + errorCode + ", errorDesc:" + errorDescription, Toast.LENGTH_SHORT).show();
    }

    private val nidProfileCallback = object : NidProfileCallback<NidProfileResponse> {
        override fun onSuccess(response: NidProfileResponse) {
                val email = response.profile!!.email
                val id = response.profile!!.id
                val name = response.profile!!.name
                Log.w(TAG, "email : $email, name : $name")
                Toast.makeText(this@MainActivity, "$email, $name", Toast.LENGTH_SHORT).show()
        }
        override fun onFailure(httpStatus: Int, message: String) {
            val errorCode = NaverIdLoginSDK.getLastErrorCode().code
            val errorDescription = NaverIdLoginSDK.getLastErrorDescription()
        }
        override fun onError(errorCode: Int, message: String) {
            onFailure(errorCode, message)
        }
    }

    private fun logoutNaver() {
        //NaverIdLoginSDK.INSTANCE.logout();
        NidOAuthLogin().callDeleteTokenApi(this, object : OAuthLoginCallback {
            override fun onSuccess() {
                //서버에서 토큰 삭제에 성공한 상태입니다.
                Toast.makeText(
                    this@MainActivity,
                    "callDeleteTokenApi, onSuccess",
                    Toast.LENGTH_SHORT
                ).show()
            }

            override fun onFailure(i: Int, s: String) {
                // 서버에서 토큰 삭제에 실패했어도 클라이언트에 있는 토큰은 삭제되어 로그아웃된 상태입니다.
                // 클라이언트에 토큰 정보가 없기 때문에 추가로 처리할 수 있는 작업은 없습니다.
                Log.d(TAG, "errorCode: ${NaverIdLoginSDK.getLastErrorCode().code}")
                Log.d(TAG, "errorDesc: ${NaverIdLoginSDK.getLastErrorDescription()}")
            }

            override fun onError(i: Int, s: String) {
                // 서버에서 토큰 삭제에 실패했어도 클라이언트에 있는 토큰은 삭제되어 로그아웃된 상태입니다.
                // 클라이언트에 토큰 정보가 없기 때문에 추가로 처리할 수 있는 작업은 없습니다.
                onFailure(i, s)
            }
        })
    }
}​
이제 앱을 실행해보면 다음과 같은 네이버 로그인 허용 팝업이 표시됩니다.
네이버 아이디와 애플리케이션의 연동을 해제하는 기능은 NidOAuthLogin().callDeleteTokenApi() 메서드로 구현합니다.
연동을 해제하면 클라이언트에 저장된 토큰과 서버에 저장된 토큰이 모두 삭제됩니다.

접근 토큰으로 프로필 정보를 가져올 때는 NidOAuthLogin().callProfileApi() 메서드를 사용합니다.