티스토리 뷰

반응형

출처. Naver Developer

 

소셜 로그인하면 생각나는 로그인이 몇 가지 있습니다. 혹시 네이버 로그인을 생각하신 분이 계실지 모르겠네요.

 

이번 시간은 네이버 로그인을 사용하는 방법에 대해서 간단히 공유 하겠습니다.

 

Naver Developer 에서 앱 설정하기

네이버 로그인을 하기 위해서는 Naver Developer에서 내 애플리케이션 을 생성해야합니다.

애플리케이션 생성은 가이드에 맞춰 따라하면 되기에 생성 이후를 소개하겠습니다.

 

라이브러리 구성하기

1. Naver Developer 사이트에서 SDK을 다운 받습니다. 네이버 SDK 다운로드
2. Android 프로젝트의 libs 폴더 밑에 naveridlogin_android_sdk_4.x.x.aar 파일을 복사합니다.
3. 프로젝트의 build.gradle에 dependencies을 추가합니다.


(app) build.gradle

dependencies {
    implementation files('libs/naveridlogin_android_sdk_4.2.5.aar')
    implementation 'com.android.support:appcompat-v7:25.3.1'
    implementation 'com.android.support:support-core-utils:25.3.1'
    implementation 'com.android.support:customtabs:25.3.1'
    implementation 'com.android.support:support-v4:25.3.1'
}

만약 ProGuard을 사용하신다면 pro guard-project.txt을 수정하여 ProGuard 적용 대상에서 네이버 아이디로 로그인 라이브러리 라이브러리 파일을 제외 합니다.

-keep public class com.nhn.android.naverlogin.** {
       public protected *;
}

 

라이브러리 사용하기

네이버 라이브러리 사용하려면 로그인 인스턴스를 초기화해야 합니다.

mOAuthLoginModule = OAuthLogin.getInstance();
mOAuthLoginModule.init(
	OAuthSampleActivity.this
	,OAUTH_CLIENT_ID  
	,OAUTH_CLIENT_SECRET
	,OAUTH_CLIENT_NAME
	//,OAUTH_CALLBACK_INTENT
	// SDK 4.1.4 버전부터는 OAUTH_CALLBACK_INTENT변수를 사용하지 않습니다.
);

OAUTH_CLIENT_ID : 애플리케이션 등록 후 발급받은 클라이언트 아이디

OAUTH_CLIENT_SECRET : 애플리케이션 등록 후 발급받은 클라이언트 시크릿

OAUTH_CLIENT_NAME : 네이버 앱 로그인 화면에 표시할 애플리케이션 이름

 

로그인

로그인 방법은 OAuthLoginButton 객체를 추가하여 사용하는 방법과 startOAutoLoginActivity() 메서드를 이용한 로그인 방법으로 나눠집니다.

 

1. OAuthLoginButton으로 로그인 하기

레이아웃 파일에 다음과 같이 추가합니다.

<com.nhn.android.naverlogin.ui.view.OAuthLoginButton
      android:id="@+id/buttonOAuthLoginImg"
      android:layout_width="wrap_content"
      android:layout_height="50dp" />

액티비티 로그인 종료 되었을 때 실행할 OAuthLoginHandler클래스와 배경타입을 등록하는 코드를 추가합니다.

 

참고로 OAuthLoginButton 객체를 사용 시 반드시 네이버에서 제공하는 로그인 버튼 가이드를 따라야합니다.

mOAuthLoginButton = (OAuthLoginButton) findViewById(R.id.buttonOAuthLoginImg);
mOAuthLoginButton.setOAuthLoginHandler(mOAuthLoginHandler);
mOAuthLoginButton.setBgResourceId(R.drawable.img_loginbtn_usercustom);

 

2. startOAuthLoginActivity() 메서드로 로그인 하기

OAuthLogin.statOAuthLoginActivity() 메서드를 직접 실행해 로그인하면 먼저 갱신 토큰이 있는지 확인합니다.

  • 갱신 토큰이 있으면 접근 토큰의 갱신을 시도합니다. − 갱신에 성공하면 OAuthLoginHandler 객체가 호출됩니다. − 갱신에 실패하면 로그인 창이 나타납니다.

  • 갱신 토큰이 없으면 로그인 창이 나타납니다.

※ 접근 토큰 갱신 관련 주의
접근토큰은 일정 시간(현재 1시간)이 지나면 만료되기 때문에 만료시간이 지난 경우 refreshAccessToken() 을 호출해서 access token 을 갱신해줘야 합니다. 또한 refreshAccessToken() 을 사용하시는 경우 메쏘드의 실행이 끝나면 access token 을 받을 수 있기 때문에 좀 더 편리하게 개발하실 수 있습니다.

 

접근 토큰 얻기

로그인에 성공했을 때는 OAuthLogin.getAccessToken() 메서드로 접근 토큰 정보를 얻을 수 있습니다.

로그인에 실패했다면 OAuthLogin.getLastErrorCode() 메서드나 OAuthLogin.getLastErrorDesc() 메서드로 실패 이유와 에러 코드를 얻을 수 있습니다.

 

로그아웃

애플리케이션에서 로그아웃할 때는 OAuthLogin.logout() 메서드를 호출합니다.

mOAuthLoginModule.logout(mContext);

 

소스코드

네이버 로그인 구성 소스는 아래와 같이 정의 할 수 있습니다.

 

LoginActivity.kt

class LoginActivity : AppCompatActivity() {
    companion object {
        private val TAG = LoginActivity::class.java!!.getSimpleName();
    }

    private lateinit var nhnOAuthLoginModule: OAuthLogin

    /**
     * ##########################
     *  Override Method
     * ##########################
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        //네이버 로그인
        nhnOAuthLoginModule = OAuthLogin.getInstance()
        nhnOAuthLoginModule.init(this, getString(R.string.nhn_oauth_client_id)
            ,getString(R.string.nhn_oauth_client_secret)
            ,getString(R.string.nhn_oauth_client_name))

        initOnClickListener()
    }
    
    /**
     * 로그인 성공 시 호출
     * */
    fun successLogin(){
        startActivity(Intent(this, MainActivity::class.java))
        finish()
    }
    private fun initOnClickListener(){
        //네이버 로그인
        btnNaverLogin.setOnClickListener {
            nhnSignIn()
        }
    }

    /**
     * 네이버 로그인 콜백
     */
    private fun nhnSignIn(){
        // 연동 해제 시 주석 풀기 (클라이언트, 서버 모두 삭제)
//        val isSuccessDeleteToken = nhnOAuthLoginModule.logoutAndDeleteToken(this@LoginActivity)
//        nhnOAuthLoginModule.logout(this@LoginActivity)

        if(nhnOAuthLoginModule.getState(this@LoginActivity) == OAuthLoginState.OK){
            LogUtils.d(TAG, "Nhn status don't need login")
            RequestNHNLoginApiTask().execute()
        }else{
            LogUtils.d(TAG, "Nhn status need login")
            nhnOAuthLoginModule.startOauthLoginActivity(this, @SuppressLint("HandlerLeak")
                object: OAuthLoginHandler(){
                    override fun run(success: Boolean) {
                        if (success) {
                            val accessToken = nhnOAuthLoginModule.getAccessToken(this@LoginActivity)
                            val refreshToken = nhnOAuthLoginModule.getRefreshToken(this@LoginActivity)
                            val expiresAt = nhnOAuthLoginModule.getExpiresAt(this@LoginActivity)
                            val tokenType = nhnOAuthLoginModule.getTokenType(this@LoginActivity)
                            Log.i(TAG, "nhn Login Access Token : $accessToken")
                            Log.i(TAG, "nhn Login refresh Token : $refreshToken")
                            Log.i(TAG, "nhn Login expiresAt : $expiresAt")
                            Log.i(TAG, "nhn Login Token Type : $tokenType")
                            Log.i(TAG, "nhn Login Module State : " + nhnOAuthLoginModule.getState(this@LoginActivity).toString())
                            successLogin()
                        } else {
                            val errorCode = nhnOAuthLoginModule.getLastErrorCode(this@LoginActivity).getCode()
                            val errorDesc = nhnOAuthLoginModule.getLastErrorDesc(this@LoginActivity)
                            Toast.makeText(this@LoginActivity, "errorCode:$errorCode, errorDesc:$errorDesc", Toast.LENGTH_SHORT).show()
                        }
                    }
                })
        }
    }

    /**
     * NHN Access Token 으로 앱 로그인
     */
    inner class RequestNHNLoginApiTask : AsyncTask<Void, Void, String>() {
        override fun onPostExecute(result: String?) {
            LogUtils.d(TAG, "onPreExecute : $result")

            val startToken = "<message>"
            val endToken = "</message>"

            val startIndex = result?.indexOf(startToken) ?: -1
            val endIndex = result?.indexOf(endToken) ?: -1

            if (startIndex == -1 || endIndex <= 0){
                return
            }
            val message = result?.substring(startIndex + startToken.length, endIndex)?.trim()

            if(message.equals("success")){
                LogUtils.d(TAG, "Success RequestNHNLoginApiTask")
                successLogin()
            }else{
                LogUtils.e(TAG, "Login Fail")
            }
        }

        override fun doInBackground(vararg params: Void?): String {
            val url = "https://apis.naver.com/nidlogin/nid/getHashId_v2.xml"
            val at = nhnOAuthLoginModule.getAccessToken(this@LoginActivity)
            return nhnOAuthLoginModule.requestApi(this@LoginActivity, at, url)
        }

        override fun onPreExecute() {
        }
    }
}

 

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/layout_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".login.LoginActivity">   
    <Button
            android:text="네이버 로그인하기"
            android:layout_width="0dp"
            android:textStyle="bold"
            android:textColor="@android:color/white"
            android:layout_height="@dimen/_45sdp"
            android:textSize="@dimen/_13sdp"
            android:background="@color/naver_green"
            android:id="@+id/btnNaverLogin" android:layout_marginBottom="30dp"
            app:layout_constraintBottom_toTopOf="@+id/btnGoogleLogin" app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
    />
</android.support.constraint.ConstraintLayout>

 

마무리

네이버 아이디로 로그인을 알아봤습니다.

네이버 SDK 를 제공하여 보다 편하게 인증을 받을 수 있었으나 java 소스로 되어 있는 것을 kotlin으로 변경하여 사용하는데 고민이 필요했습니다. (문법)

부족한 설명은 네이버 디벨로퍼 사이트에서 확인할 수 있습니다.

 

 

 

 

 

 

 

반응형
댓글