Giter Club home page Giter Club logo

naveridlogin-sdk-android's Introduction

Naver Login SDK for Android

Naver Login Overview

NAVER Login let users to use the OAuth 2.0-based security feature of NAVER when they are using non-NAVER services.

It is a convenient and secure way for users to log into your application with the NAVER ID and password; they do not have to remember their IDs and password of your application. It is recommended to add NAVER Login to your application if you want to make people who hate complicated signups to join your application or stop users leaving your application because they forget their accounts.

Naver Login for Android

The NAVER Login library for Android enables you to easily add the login, logout, and token management features to your application.

How to use NaverIdLogin SDK for Android? (korean)

Need help?

Dependent libraries

Naver Login for Android uses libraries below.

  • org.jetbrains.kotlin:kotlin-stdlib:1.6.21
  • org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9
  • androidx.appcompat:appcompat:1.3.1
  • androidx.legacy:legacy-support-core-utils:1.0.0
  • androidx.browser:browser:1.4.0
  • androidx.constraintlayout:constraintlayout:1.1.3
  • androidx.security:security-crypto:1.1.0-alpha06
  • androidx.core:core-ktx:1.3.0
  • androidx.fragment:fragment-ktx:1.3.6
  • androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0
  • com.squareup.retrofit2:retrofit:2.9.0
  • com.squareup.retrofit2:converter-gson:2.9.0
  • com.squareup.moshi:moshi-kotlin:1.11.0
  • com.squareup.okhttp3:logging-interceptor:4.2.1
  • com.airbnb.android:lottie:3.1.0

네아로SDK for Android (네이버 아이디로 로그인 SDK)

Android용 네아로 SDK는 서드파티 애플리케이션에서 네이버 아이디로 로그인이 제공하는 로그인, 로그아웃, 토큰 관리 등의 기능을 쉽게 구현할 수 있게 합니다.

네이버 아이디로 로그인이란?

네이버 아이디로 로그인 SDK 적용가이드

네이버 아이디로 로그인 문의

사용하는 라이브러리

네아로 SDK에서 사용하는 라이브러리는 다음과 같습니다.

  • org.jetbrains.kotlin:kotlin-stdlib:1.6.21
  • org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9
  • androidx.appcompat:appcompat:1.3.1
  • androidx.legacy:legacy-support-core-utils:1.0.0
  • androidx.browser:browser:1.4.0
  • androidx.constraintlayout:constraintlayout:1.1.3
  • androidx.security:security-crypto:1.1.0-alpha06
  • androidx.core:core-ktx:1.3.0
  • androidx.fragment:fragment-ktx:1.3.6
  • androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0
  • com.squareup.retrofit2:retrofit:2.9.0
  • com.squareup.retrofit2:converter-gson:2.9.0
  • com.squareup.moshi:moshi-kotlin:1.11.0
  • com.squareup.okhttp3:logging-interceptor:4.2.1
  • com.airbnb.android:lottie:3.1.0

License

See LICENSE for full license text.

Copyright 2017 Naver Corp.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

naveridlogin-sdk-android's People

Contributors

dayeonlee-0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

naveridlogin-sdk-android's Issues

5.1.0연동중 빌드시 profile api 오류

5.1.0 연동중입니다.
빌드시 profile api에서 오류가 나는데 원인을 모르겠네요.
error: cannot access Job
login.callProfileApi(new NidProfileCallback() {
^
class file for kotlinx.coroutines.Job not found

네이버 아이디 로그인시 에러 발생(java.lang.IllegalArgumentException)

네이버 아이디 로그인시 간헐적으로 Crash Report 되고 있습니다.
확인 부탁드립니다.
SDK 버전은 5.1.0 입니다.

Fatal Exception: java.lang.IllegalArgumentException: View=DecorView@3aecdd8[NidOAuthBridgeActivity] not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:648)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:548)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:162)
at android.app.Dialog.dismissDialog(Dialog.java:778)
at android.app.Dialog.dismiss(Dialog.java:754)
at androidx.appcompat.app.AppCompatDialog.dismiss(AppCompatDialog.java:140)
at com.navercorp.nid.progress.NidProgressDialog.hideProgress(NidProgressDialog.java:73)
at com.navercorp.nid.oauth.NidOAuthLogin$accessToken$1.invokeSuspend(NidOAuthLogin.java:239)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:56)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

SDK v5.1.0 kotlin.UninitializedPropertyAccessException

안녕하세요.

네아로 SDK v5.1.0 버전에서 kotlin.UninitializedPropertyAccessException 이 발생합니다.

Caused by kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
       at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:33)
       at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16)
       at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28)
       at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27)
       at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
       at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27)
       at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84)
       at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53)
       at com.navercorp.nid.oauth.NidOAuthBridgeActivity.initData(NidOAuthBridgeActivity.kt:45)
       at com.navercorp.nid.oauth.NidOAuthBridgeActivity.onCreate(NidOAuthBridgeActivity.kt:75)
       at android.app.Activity.performCreate(Activity.java:8054)
       at android.app.Activity.performCreate(Activity.java:8034)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1341)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3688)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3864)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7870)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

분석해본 결과 EncryptedPreferences 클래스에 정의된 lateinit 코드로 인해 크래시가 발생하는 것으로 보입니다.

object EncryptedPreferences {
    private lateinit var context: Context
}

찾아낸 재현 조건은 다음과 같습니다.

  • 메모리 부족으로 인해 앱 프로세스 종료

재현 경로

  1. 서비스 앱 실행 -> 네아로 버튼 클릭으로 네이버 로그인 페이지로 이동 (이때 서비스 앱의 activity 는 onPause 상태로 변경)
  2. (조건) 이후 메모리 부족으로 서비스 앱의 프로세스가 종료된 경우
  3. 네이버 로그인 페이지에서 로그인 요청 및 취소를 통해 서비스 앱으로 복귀
  4. 서비스 앱이 재생성되며 네아로 SDK 에 포함된 클래스 EncryptedPreferences 객체도 재생성 (context 값이 없어짐)
  5. 네아로 SDK 관련 코드 흐름 (위 스택 참고) 에서 context 에 접근하며 크래시 발생

예상 해결 방안

  • lateinit 으로 선언된 context 로부터 kotlin.UninitializedPropertyAccessException 가 발생하지 않도록 값을 초기화할 수 있는 기회를 제공해야 할 것 같습니다.

참고

  • 이 이슈는 #40 와 동일한 이슈일 수 있습니다.

감사합니다.

fix: client secret 노출

client secret 은 Client(OAuth 용어. e.g. 이 라이브러리를 사용하는 앱(=User Agent)의 "운영사") 와 Authorization Server(OAuth 용어. e.g. naver) 사이에만 공유해야 합니다.

client secret 은 Client Impersonation 문제를 해결하기 위한 것으로, 유저(Resource Owner)가 알게 된다면 의미가 없습니다.

Screenshot from 2021-11-02 17-43-23

하지만 본 라이브러리와 공식 문서에서는 위와 같이 client secret 을 앱(User Agent)에서 접근가능하도록 요구하고 있습니다.
이는 client secret 의 의미를 상실케 합니다.

예를 들어, kakao 의 경우, 동일한 방식으로 User Agent 에서 accessToken 을 얻되, client id 만을 요구합니다.

client id 만으로 가능하도록 patch 를 부탁드립니다.

[5.1.0] NidProgressDialog WindowManager$BadTokenException

SDK 5.1.0

해당 이슈와 동일한 이슈가 발생합니다.

android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4ee548e is not valid; is your activity running?
    at android.view.ViewRootImpl.setView(ViewRootImpl.java:1147)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:471)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
    at android.app.Dialog.show(Dialog.java:507)
    at ma.a.showProgress(NidProgressDialog.kt:8)
    at ma.a.showProgress(NidProgressDialog.kt:3)
    at ma.a.showProgress(NidProgressDialog.kt:1)
    at da.f$b.invokeSuspend(NidOAuthLogin.kt:4)
    at kotlin.coroutines.jvm.internal.a.resumeWith(ContinuationImpl.kt:4)
    at kotlinx.coroutines.z0.run(DispatchedTask.kt:18)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:8154)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

이것이 잘못된 usage 때문인지는 모르겠지만, NidProgressDialog 내부의 AppCompatDialogshow 할 때, 방어 로직이 들어가면 좋을 것 같습니다.

package com.navercorp.nid.progress

import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import androidx.appcompat.app.AppCompatDialog
import androidx.appcompat.widget.AppCompatTextView
import com.airbnb.lottie.LottieAnimationView
import com.nhn.android.oauth.R

/**
 *
 * Created on 2021.10.22
 * Updated on 2021.10.22
 *
 * @author Namhoon Kim. ([email protected])
 *         Naver Authentication Platform Development.
 *
 * 네이버 공통 Nid Progress Dialog
 */
class NidProgressDialog {
    private var context: Context
    private var dialog: AppCompatDialog
    private var message: AppCompatTextView? = null
    private var animation: LottieAnimationView? = null

    constructor(context: Context) {
        this.context = context
        this.dialog = AppCompatDialog(context)

        init(null)
    }

    private val isSafeForManipulateDialogVisibility get() = (context as? Activity)?.isFinishing != true

    private fun init(cancelListener: DialogInterface.OnCancelListener?) {
        dialog.setCancelable(true)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.setContentView(R.layout.nid_progress_dialog)

        message = dialog.findViewById(R.id.nid_progress_dialog_message)
        animation = dialog.findViewById(R.id.nid_progress_dialog_animation)
    }

    fun showProgress(resourceId: Int) {
        showProgress(context.resources.getString(resourceId))
    }

    fun showProgress(resourceId: Int, cancelListener: DialogInterface.OnCancelListener? = null) {
        showProgress(context.resources.getString(resourceId), cancelListener)
    }

    fun showProgress(msg: String) {
        showProgress(msg, null)
    }

    fun showProgress(msg: String, cancelListener: DialogInterface.OnCancelListener? = null) {
        message?.let {
            it.text = msg
        }

        cancelListener?.let {
            dialog.setOnCancelListener(cancelListener)
        }

        animation?.playAnimation()

        if (isSafeForManipulateDialogVisibility) {
            dialog.show()
        }
    }

    fun hideProgress() {
        if (dialog.isShowing && isSafeForManipulateDialogVisibility) {
            animation?.pauseAnimation()
            dialog.dismiss()
        }
    }
}

AGP(Android Gradle Plugin) 4.1.0 적용시 빌드 에러 발생

AGP(Android Gradle Plugin) 4.1.0 적용시 빌드 에러가 발생합니다.
(프로젝트 libs 폴더 내부에 naveridlogin_android_sdk_4.2.6.aar 를 저장하는 경우...)

Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error). The following direct local .aar file dependencies of the :Main project caused this error:

위 이슈에 대한 가이드가 필요해보입니다.

oauth-5.0.1.aar 파일 어디에 있나요?

네이버 Developers에서 Android용 네아로SDK를 Github에서도 다운받을 수 있다고 했는데
해당 파일이 어디에 있는지 모르겠어서 글 남깁니다!
code를 zip파일로 다운받아 aar파일을 검색해봤는데 보이지 않습니다.
감사합니다.

네트워크 단절 환경에서 startOauthLoginActivity 콜백이 오지 않습니다.

제목 그대로 입니다.

재현 방법

  1. 디바이스를 비행기 모드로 변경 합니다.
  2. startOauthLoginActivity 호출
  3. 네트워크 오류 팝업 노출 확인
  4. 취소

startOauthLoginActivity 함수 내 checkConnectivity 콜백의 retry 가 false 에 대한 처리를 해야 할 것 같습니다.

버그가 빨리 고쳐 졌으면 좋겠네요!
감사합니다. 좋은 하루 되세요!

5.1.1 네아로 호출시 오류가 발생합니다.

2022-06-24 13:57:01.847 2415-2415/com.?.? W/AndroidKeystoreAesGcm: encountered a potentially transient KeyStore error, will wait and retry
javax.crypto.AEADBadTagException
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:617)
at javax.crypto.Cipher.doFinal(Cipher.java:2113)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:115)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:97)
at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:206)
at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:107)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:32)
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27)
at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84)
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53)
at com.navercorp.nid.oauth.EncryptedPreferences.migration(EncryptedPreferences.kt:110)
at com.navercorp.nid.oauth.EncryptedPreferences.setContext(EncryptedPreferences.kt:44)
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56)
at com.?.?.MainActivity.startNaverLogin$lambda-9(MainActivity.kt:484)
at com.?.?.MainActivity.$r8$lambda$_fmXxE5yS5OybJ5uyqlDD8OuIS4(Unknown Source:0)
at com.?.?.MainActivity$$ExternalSyntheticLambda2.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: android.security.KeyStoreException: Signature/MAC verification failed
at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:408)
at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
at android.security.KeyStoreOperation.finish(KeyStoreOperation.java:127)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.finish(KeyStoreCryptoOperationChunkedStreamer.java:228)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:181)
at android.security.keystore2.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:396)
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:609)
at javax.crypto.Cipher.doFinal(Cipher.java:2113) 
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:115) 
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:97) 
at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:206) 
at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:107) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238) 
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155) 
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120) 
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:32) 
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16) 
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28) 
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27) 
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) 
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27) 
at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84) 
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53) 
at com.navercorp.nid.oauth.EncryptedPreferences.migration(EncryptedPreferences.kt:110) 
at com.navercorp.nid.oauth.EncryptedPreferences.setContext(EncryptedPreferences.kt:44) 
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56) 
at com.?.?.MainActivity.startNaverLogin$lambda-9(MainActivity.kt:484) 
at com.?.?.MainActivity.$r8$lambda$_fmXxE5yS5OybJ5uyqlDD8OuIS4(Unknown Source:0) 
at com.?.?.MainActivity$$ExternalSyntheticLambda2.run(Unknown Source:2) 
at android.os.Handler.handleCallback(Handler.java:938) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8669) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
2022-06-24 13:57:01.925 2415-2415/com.?.? W/AndroidKeysetManager: cannot decrypt keyset:
javax.crypto.AEADBadTagException
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:617)
at javax.crypto.Cipher.doFinal(Cipher.java:2113)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:115)
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:101)
at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:206)
at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:107)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:32)
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27)
at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84)
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53)
at com.navercorp.nid.oauth.EncryptedPreferences.migration(EncryptedPreferences.kt:110)
at com.navercorp.nid.oauth.EncryptedPreferences.setContext(EncryptedPreferences.kt:44)
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56)
at com.?.?.MainActivity.startNaverLogin$lambda-9(MainActivity.kt:484)
at com.?.?.MainActivity.$r8$lambda$_fmXxE5yS5OybJ5uyqlDD8OuIS4(Unknown Source:0)
at com.?.?.MainActivity$$ExternalSyntheticLambda2.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: android.security.KeyStoreException: Signature/MAC verification failed
at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:408)
at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
at android.security.KeyStoreOperation.finish(KeyStoreOperation.java:127)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.finish(KeyStoreCryptoOperationChunkedStreamer.java:228)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:181)
at android.security.keystore2.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:396)
at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:609)
at javax.crypto.Cipher.doFinal(Cipher.java:2113) 
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:115) 
at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:101) 
at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:206) 
at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:107) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287) 
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238) 
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155) 
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120) 
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:32) 
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16) 
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28) 
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27) 
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) 
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27) 
at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84) 
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53) 
at com.navercorp.nid.oauth.EncryptedPreferences.migration(EncryptedPreferences.kt:110) 
at com.navercorp.nid.oauth.EncryptedPreferences.setContext(EncryptedPreferences.kt:44) 
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56) 
at com.?.?.MainActivity.startNaverLogin$lambda-9(MainActivity.kt:484) 
at com.?.?.MainActivity.$r8$lambda$_fmXxE5yS5OybJ5uyqlDD8OuIS4(Unknown Source:0) 
at com.?.?.MainActivity$$ExternalSyntheticLambda2.run(Unknown Source:2) 
at android.os.Handler.handleCallback(Handler.java:938) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8669) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
2022-06-24 13:57:01.926 2415-2415/com.?.? D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.?.?, PID: 2415
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:581)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
Caused by: com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1566)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1664)
at com.google.crypto.tink.proto.Keyset.parseFrom(Keyset.java:957)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read(SharedPrefKeysetReader.java:84)
at com.google.crypto.tink.CleartextKeysetHandle.read(CleartextKeysetHandle.java:58)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:328)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:32)
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27)
at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84)
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53)
at com.navercorp.nid.oauth.EncryptedPreferences.migration(EncryptedPreferences.kt:110)
at com.navercorp.nid.oauth.EncryptedPreferences.setContext(EncryptedPreferences.kt:44)
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56)
at com.?.?.MainActivity.startNaverLogin$lambda-9(MainActivity.kt:484)
at com.?.?.MainActivity.$r8$lambda$_fmXxE5yS5OybJ5uyqlDD8OuIS4(Unknown Source:0)
at com.?.?.MainActivity$$ExternalSyntheticLambda2.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8669)
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 

기종별로 뭔가 다른점이있는지
NaverIdLoginSDK.initialize(
context,
NAVER_CLIENT_ID,
NAVER_SECRET_KEY,
NAVER_CLIENT_NAME
)
를 호출하는데 SM-F926N (폴드 3) 에서는 오류가 발생하지 않으나
SM-G986N (S20+ 5G) 기종에서 사용할때 해당 오류와 함께 강제종료가 발생합니다.
둘다 OS 버전은 Android 12 SDK 31 입니다

앱 패키지 명은 com.?.? 로 가린점 양해 부탁드립니다.
오류 확인부탁드립니다.

[앱 크래시] OAuthLoginActivity.onDestroy NPE

OAuthLoginActivity.onDestroy() 시점에 OAuthLogin.mOAuthLoginHandler 스태틱 변수 참조때문에
NPE 가 자주 발생합니다.
스태틱 변수의 관리를 세밀하게 하지 못할거라면, 안전하게 널체크를 추가해주면 좋겠습니다.

Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'void com.nhn.android.naverlogin.OAuthLoginHandler.run(boolean)' on a null object reference
       at com.nhn.android.naverlogin.ui.OAuthLoginActivity.onDestroy + 138(OAuthLoginActivity.java:138)
       at android.app.Activity.performDestroy + 7418(Activity.java:7418)
       at android.app.Instrumentation.callActivityOnDestroy + 1307(Instrumentation.java:1307)
       at android.app.ActivityThread.performDestroyActivity + 4629(ActivityThread.java:4629)
       at android.app.ActivityThread.handleDestroyActivity + 4663(ActivityThread.java:4663)
       at android.app.servertransaction.DestroyActivityItem.execute + 39(DestroyActivityItem.java:39)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState + 145(TransactionExecutor.java:145)
       at android.app.servertransaction.TransactionExecutor.execute + 70(TransactionExecutor.java:70)
       at android.app.ActivityThread$H.handleMessage + 1864(ActivityThread.java:1864)
       at android.os.Handler.dispatchMessage + 106(Handler.java:106)
       at android.os.Looper.loop + 205(Looper.java:205)
       at android.app.ActivityThread.main + 6993(ActivityThread.java:6993)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run + 493(RuntimeInit.java:493)
       at com.android.internal.os.ZygoteInit.main + 884(ZygoteInit.java:884)

NaverIdLoginSDK().initialize() 호출시 kotlin.UninitializedPropertyAccessException

NaverIdLoginSDK().initialize() 호출시 showDevelopersLog() 를 호출하지 않거나, 파라미터에 false 가 들어가면 kotlin.UninitializedPropertyAccessException 발생합니다.

  • NidLog 클래스 init() 함수에서 변수 초기화를 하는데, 호출하는 부분이 존재하지 않습니다.
  • init { } 블럭으로 바꾸던지, 변수에 lateinit 이 없고 초기화가 되어 있어야 합니다.
// 문제되는 가이드소스
NaverIdLoginSDK.apply {
    showDevelopersLog(true) <----- false 대입시 crash 발생
    initialize(...)
}
// 에러
kotlin.UninitializedPropertyAccessException: lateinit property instance has not been initialized
        at sb.a.f(NaverIdLoginSDK.kt:12)

네이버 로그인 초기화시 InvalidProtocolBufferException 발생

네아로 5.0.1 사용중입니다. 안드로이드 12기기에서 아래 오류가 발생합니다. 네아로에서 사용중인 crypto 라이브러리(androidx.security:security-crypto:1.1.0-alpha03)에서 발생하는 문제같습니다.

관련 문서: tink-crypto/tink#413 (comment)

☛ 앱 설정에서 데이터 삭제한 후 앱 실행하면 오류가 안나네요

java.lang.RuntimeException: Unable to create application : com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7511)
at android.app.ActivityThread.access$1700(ActivityThread.java:310)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2281)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1566)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1664)
at com.google.crypto.tink.proto.Keyset.parseFrom(Keyset.java:957)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read(SharedPrefKeysetReader.java:84)
at com.google.crypto.tink.CleartextKeysetHandle.read(CleartextKeysetHandle.java:58)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:328)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:22)
at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:13)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:18)
at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:17)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:17)
at com.navercorp.nid.oauth.EncryptedPreferences.set(EncryptedPreferences.kt:69)
at com.navercorp.nid.oauth.NidOAuthPreferencesManager.setClientId(NidOAuthPreferencesManager.kt:52)
at com.navercorp.nid.NaverIdLoginSDK.initialize(NaverIdLoginSDK.kt:56)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1211)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7506)
at android.app.ActivityThread.access$1700(ActivityThread.java:310) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2281) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8663) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 

com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException 발생

androidx.startup 을 통해 NaverLoginSDK 를 초기화 시, crypto 관련 오류가 발생되고 있습니다.
확인 부탁드립니다.

java.lang.RuntimeException: 
  at android.app.ActivityThread.installProvider (ActivityThread.java:8208)
  at android.app.ActivityThread.installContentProviders (ActivityThread.java:7711)
  at android.app.ActivityThread.handleBindApplication (ActivityThread.java:7465)
  at android.app.ActivityThread.access$1700 (ActivityThread.java:310)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2281)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8646)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:567)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)
Caused by: androidx.startup.StartupException: 
  at androidx.startup.AppInitializer.doInitialize (AppInitializer.java:162)
  at androidx.startup.AppInitializer.discoverAndInitialize (AppInitializer.java:198)
  at androidx.startup.InitializationProvider.onCreate (InitializationProvider.java:38)
  at android.content.ContentProvider.attachInfo (ContentProvider.java:2516)
  at android.content.ContentProvider.attachInfo (ContentProvider.java:2486)
  at android.app.ActivityThread.installProvider (ActivityThread.java:8203)
Caused by: com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException: 
  at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom (GeneratedMessageLite.java:1566)
  at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom (GeneratedMessageLite.java:1664)
  at com.google.crypto.tink.proto.Keyset.parseFrom (Keyset.java:957)
  at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read (SharedPrefKeysetReader.java:84)
  at com.google.crypto.tink.CleartextKeysetHandle.read (CleartextKeysetHandle.java:58)
  at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read (AndroidKeysetManager.java:328)
  at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset (AndroidKeysetManager.java:287)
  at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build (AndroidKeysetManager.java:238)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java:155)
  at androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java:120)
  at com.navercorp.nid.oauth.EncryptedPreferences.init (EncryptedPreferences.kt:22)
  at com.navercorp.nid.oauth.EncryptedPreferences.access$init (EncryptedPreferences.kt:13)
  at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke (EncryptedPreferences.kt:18)
  at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke (EncryptedPreferences.kt:17)
  at kotlin.SynchronizedLazyImpl.getValue (LazyJVM.kt:74)
  at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences (EncryptedPreferences.kt:17)
  at com.navercorp.nid.oauth.EncryptedPreferences.set (EncryptedPreferences.kt:69)
  at com.navercorp.nid.oauth.NidOAuthPreferencesManager.setClientId (NidOAuthPreferencesManager.kt:52)
  at com.navercorp.nid.NaverIdLoginSDK.initialize (NaverIdLoginSDK.kt:55)
  at com.-.NaverSDKInitializer.create (NaverSDKInitializer.kt:12)
  at com.-.NaverSDKInitializer.create (NaverSDKInitializer.kt:9)
  at androidx.startup.AppInitializer.doInitialize (AppInitializer.java:155)

5.0.0 guide 문서 내용(4. 초기화) 업데이트 요청

아래 초기화 관련 내용중에 메서드 호출부분이 정정되어야 합니다. 계층구조를 표현하기 위하여 dot 으로 구분하여 표시할 수도 있지만, NaverIdLoginSDK.initialize() 과 같이 실제 static 메서드 호출예제와 혼합하여 사용되어져, 가이드 문서에서 혼동을 주고 있습니다.

  • NidOAuthLogin.logout() --> NidOAuthLogin().logout()
  • NidOAuthLogin.callDeleteTokenApi() --> NidOAuthLogin().callDeleteTokenApi()

https://developers.naver.com/docs/login/android/android.md#4--%EC%B4%88%EA%B8%B0%ED%99%94

4. 초기화
네아로SDK를 애플리케이션에 적용하려면 다음과 같은 코드를 추가해 네이버 로그인 인스턴스를 초기화합니다.
NaverIdLoginSDK.initialize(context, {OAUTH_CLIENT_ID}, {OAUTH_CLIENT_SECRET}, {OAUTH_CLIENT_NAME})

...
중략
...

참고
NaverIdLoginSDK.initialize() 메서드가 여러 번 실행돼도 기존에 저장된 접근 토큰(access token)과 갱신 토큰(refresh token)은 삭제되지 않습니다.
기존에 저장된 접근 토큰과 갱신 토큰을 삭제하려면 NidOAuthLogin.logout() 메서드나 NidOAuthLogin.callDeleteTokenApi() 메서드를 호출합니다.

5.2.0에 `authenticate` API가 이상적이지 않습니다.

갑자기 5.2.0에 이걸 인자로 받는 이유를 잘 모르겠는데, API 자체가 일관성있게 작동하지 않습니다.

  • authenticate 함수에 AcitivtyResultaLauncher를 인자로 받음으로써 Native가 아닌 다른 플랫폼에서 해당 SDK를 이용하려 할 때, Activity의 Lifecycle과의 어색한 연동때문에 사용하기가 까다로워집니다. (Activity를 직접적으로 사용하지 않는 플랫폼에서 registerForActivityResult 를 초기화하는 시점을 결정할 수 없고(하지만 이는 독스에 따르면 RESUMED 전에 unconditional하게 등록되어야 합니다), Android로의 의존성이 큽니다.)
  • 코드를 자세히 본건 아니지만 Refreshtoken의 유무에 따라 어쩔땐 ActivityResultLauncher의 콜백으로 결과가 반환되고 어쩔땐 authenticate 함수의 세 번째 인자인 callback으로 결과가 반환됩니다.

제가 잘 이해한 것인진 모르겠지만 개선이 필요해보입니다.
현재 5.2.0 에서 fix된 여러 이슈들이 프로젝트에 문제를 일으키고 있는 상황이라 rn package 를 손보고 있는데, 5.2.0 로 내부적인 코드를 변경하는데 애로사항이 있습니다.

플레이스토 앱 제출시 에러

Version of naveridlogin-android-sdk libraries
4.2.5

Expected behavior
에러 없이 플레이 스토어 리뷰 통과

Actual behavior
플레이스토어 업로드시 에러를 출력합니다.

Tested environment (Emulator? Real Device?)
Real Device

교차 앱 스크립팅
교차 앱 스크립팅에 취약한 WebView가 앱에 포함되어 있습니다. 자세한 내용은 Google 고객센터 도움말을 확인하세요.

com.nhn.android.naverlogin.ui.OAuthLoginInAppBrowserActivity.runOnlyOnce
sv:deadline:07/03/2022

SDK runs error on android11

**(context.getPackageManager().queryIntentActivities)**this function return empty in android11, but sdk use this function in (DeviceAppInfo), please update version

feat: PKCE 지원

현재 PKCE 방식을 사용할 수 없는 것으로 보입니다.

PKCE 방식은 google, facebook, github 등 여러 서비스에서 사실상 기본방식으로 쓰이고 있고, 보안성이 높아 IETF 의 OAuth 2.0 Security Best Current Practice에서도 이를 권장하고 있습니다.

kakao 의 공식 라이브러리의 경우, REST API 는 물론이고, android 에서도 PKCE 를 위한 Authorization Code 를 얻을 수 있는 방법을 제공합니다.

네이버의 경우는 REST API 에서만 PKCE 를 사용 가능하도록 되어 있습니다.

예시:
Screenshot from 2021-11-02 17-58-36

따라서 공식 네이티브 라이브러리로도 사용가능하도록 제안드립니다.

감사합니다.

기존 네아로 SDK 4.2.6 사용했다가 5.0.1로 업데이트 시 로그인 유지가 가능한가요?

안녕하세요
기존 네아로 4.2.6 사용하다가 안드로이드 12 타켓을 변경 하면서 5.0.1로 업데이트하여 작업했는데
기존에 앱을 사용하고 있다가 앱을 업데이트시 로그인이 유지 안되고 있는데 유지 안되는게 맞는건가요?
기존 로직은
OAuthLogin.getInstance().refreshAccessToken을 호출하여 acesstoken 여부로 로그인 유지 여부를 체크하였습니다.
5.0.1로 변경하면서는 방식이 변경되어 NidOAuthLogin().callRefreshAccessTokenApi 로 체크했는데 적용이 안되서
if (NidOAuthLoginState.OK == NaverIdLoginSDK.getState())
으로 체크해도 체크를 할 수 없습니다.

해당 방법을 우회할려면 어떤식으로 개발을 해야 하는지 알려주시면 감사하겠습니다.

네아로 5.x TASK 이슈

안녕하세요.
현재 네아로 task관련 이슈가 발생하여 확인 및 수정 요청 드립니다.

이슈는 다음 두가지 입니다.

  1. 다른앱(앱1) -> 네아로sdk연동앱(앱2) -> 네아로 호출 할 경우 앱1과 앱2의 task가 나눠짐
  • task가 나눠짐에 따라 네아로 화면에서 홈키등으로 화면을 벗어났다 다시 돌아올때 여러가지 사이드 이펙트가 발생함
  • 앱2에서 직접 네아로를 호출할 경우에는 task가 분리되지 않음
  1. 해당 상황을 방지하고자 앱2에서 네아로의 엑티비티에 excludeFromRecents="true"로 하여 홈키등으로 화면을 벗어났을때 네아로 엑티비티를 종료하게 할 경우
    네아로 웹 -> 정상적으로 엑티비티 종료 및 에러 콜백
    네아로 앱 -> recents에서는 사라지지만 엑티비티가 종료가 되지 않음 -> 다른 앱을 실행하는 엑션을 일으킬때 네아로 엑티비티 종료 및 에러 콜백

1번 이슈의 경우 별도의 task관리를 하지 않아도 task가 분리되며 여러 문제가 발생하게 됩니다. 네아로의 task가 분리되지 않게하거나 옵션을 줄 수 있게 수정 요청드립니다.

2번 이슈의 경우 네아로 웹 일 경우에는 홈키를 누르면 바로 ACTIVITY_IS_SINGLE_TASK 에러 콜백이 발생하지만
네아로 앱 일 경우에는 홈키를 눌러도 아무 동작을 하지 않습니다. (다른 앱을 실행하면 그때 ACTIVITY_IS_SINGLE_TASK 콜백 발생)
네이버 앱을 사용할 경우만 발생하는 현상으로 웹 인증처럼 바로 ACTIVITY_IS_SINGLE_TASK 콜백이 발생하도록 수정 요청드립니다.

Can't create handler inside thread Thread that has not called Looper.prepare()

최초 호출시에는 정상적으로 작동 하나, 로그인이 성공적으로 된 이후에 재호출을 하게 되면 Can't create handler inside thread Thread[DefaultDispatcher-worker-2,5,main] that has not called Looper.prepare() 예외가 발생합니다.

override suspend fun getNaver(): String {
        return suspendCancellableCoroutine<Result<String>> { continuation ->
            NaverIdLoginSDK.authenticate(
                activityContext, // Activity로 context 넘겨주고 있습니다.
                object : OAuthLoginCallback {
                    override fun onSuccess() {
                        val token = NaverIdLoginSDK.getAccessToken()
                        logeukes { listOf("네이버", token) }
                        continuation.resume(
                            token?.let { success(it) }
                                ?: failure(NAVER_ACCESS_TOKEN_NULL)
                        )
                    }

                    override fun onFailure(httpStatus: Int, message: String) {
                        logeukes(type = LoggerType.E) { listOf(httpStatus, message) }
                        continuation.resume(failure("$httpStatus ($message)"))
                    }

                    override fun onError(errorCode: Int, message: String) {
                        onFailure(errorCode, message)
                    }
                }
            )
        }.getOrThrow()

api는 이렇게 호출하고 있습니다. 추가 정보가 필요할 거 같은데, 코멘트 남겨주시면 추가 정보 드리겠습니다.

gradle 난독화 시 널 포인트 에러 발생

gladle
buildTypes {
release {
minifyEnabled true -> true 설정시 발생 false 설정 시 발생안함

Fatal Exception: java.lang.NullPointerException
com.navercorp.nid.profile.data.NidProfile.getId (NidProfile.java:3)
com.navercorp.nid.oauth.NidOAuthLogin$callProfileApi$1.invokeSuspend (NidOAuthLogin.java:142)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (BaseContinuationImpl.java:13)
kotlinx.coroutines.DispatchedTask.run (DispatchedTask.java:130)
android.os.Handler.handleCallback (Handler.java:938)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loopOnce (Looper.java:226)
android.os.Looper.loop (Looper.java:313)
android.app.ActivityThread.main (ActivityThread.java:8663)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:567)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)

5.1.1 로그인 크래쉬

최초 1회는 동작하고, 로그인이 되어있는 상태에서 로그인을 호출하면 발생하는 문제입니다.

2022-06-27 16:37:50.336 12523-12523/co.aienglish E/AndroidRuntime: FATAL EXCEPTION: main
Process: co.aienglish, PID: 12523
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:846)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:809)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95)
at com.navercorp.nid.progress.NidProgressDialog.init(NidProgressDialog.kt:39)
at com.navercorp.nid.progress.NidProgressDialog.(NidProgressDialog.kt:32)
at com.navercorp.nid.oauth.NidOAuthLogin.refreshToken(NidOAuthLogin.kt:198)
at com.navercorp.nid.NaverIdLoginSDK.authenticate(NaverIdLoginSDK.kt:113)
at com.dooboolab.naverlogin.RNNaverLoginModule$1.run(RNNaverLoginModule.java:131)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7850)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

INSTALL_PARSE_FAILED_MANIFEST_MALFORMED 발생 건

Android 12 Beta 환경에서 아래와 같이 빌드 에러가 발생하여 검증에 어려움이 있습니다.

com.nhn.android.naverlogin.ui.OAuthCustomTabActivity: Targeting S+ (version 10000 and above) requires that an explicit value for android:exported be defined when intent filters are present

OAuthCustomTabActivity 액티비티에 android:exported 추가 요청드립니다.
rf. https://medium.com/androiddevelopers/lets-be-explicit-about-our-intent-filters-c5dbe2dbdce0

감사합니다.

Gradle 설정 후 안되는게 있어 문의 좀 드려요

https://github.com/naver/naveridlogin-sdk-android/wiki/v5.0.1-%EC%9D%B4%EC%83%81-%EA%B0%80%EC%9D%B4%EB%93%9C

위 페이지를 참조 해서 라이브러리 등록까지 아래와 같이 다 해줬어요.
implementation 'com.navercorp.nid:oauth-jdk8:5.1.1' // jdk 8
implementation files('libs/oauth-5.1.1.aar')

그런데 4번의

NaverIdLoginSDK.initialize(context, {OAUTH_CLIENT_ID}, {OAUTH_CLIENT_SECRET},{OAUTH_CLIENT_NAME})

초기화를 진행하는 부분이 있는데 NaverIdLoginSDK 가 나오지 않는데 어떻게 해야 하나요?

그리고 추가적으로 JAVA는 지원하지 않나요?

com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException 발생

Caused by com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException
Protocol message contained an invalid tag (zero).

com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom (GeneratedMessageLite.java:1566)

androidx.security.crypto.EncryptedSharedPreferences.create (EncryptedSharedPreferences.java:120)
com.navercorp.nid.oauth.EncryptedPreferences.init (EncryptedPreferences.kt:22)
com.navercorp.nid.oauth.EncryptedPreferences.access$init (EncryptedPreferences.kt:13)
com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke (EncryptedPreferences.kt:18)
com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke (EncryptedPreferences.kt:17)
kotlin.SynchronizedLazyImpl.getValue (LazyJVM.kt:74)
com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences (EncryptedPreferences.kt:17)
com.navercorp.nid.oauth.EncryptedPreferences.set (EncryptedPreferences.kt:69)
com.navercorp.nid.oauth.NidOAuthPreferencesManager.setClientId (NidOAuthPreferencesManager.kt:52)
com.navercorp.nid.NaverIdLoginSDK.initialize (NaverIdLoginSDK.kt:55)

memory leak issue

사용 버전 : com.navercorp.nid:oauth:5.2.0
릭체크는 leak canary : 2.8.1 버전으로 사용

[case1]
10-31 11:13:33.132 7740 8439 D LeakCanary: ┬───
10-31 11:13:33.132 7740 8439 D LeakCanary: │ GC Root: System class
10-31 11:13:33.132 7740 8439 D LeakCanary: │
10-31 11:13:33.132 7740 8439 D LeakCanary: ├─ android.net.ConnectivityManager class
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Leaking: NO (a class is never leaking)
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ↓ static ConnectivityManager.sInstance
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ~~~~~~~~~
10-31 11:13:33.132 7740 8439 D LeakCanary: ├─ android.net.ConnectivityManager instance
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Leaking: UNKNOWN
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Retaining 114 B in 5 objects
10-31 11:13:33.132 7740 8439 D LeakCanary: │ mContext instance of com.navercorp.nid.oauth.activity.NidOAuthCustomTabActivity with mDestroyed = true
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ↓ ConnectivityManager.mContext
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ~~~~~~~~
10-31 11:13:33.132 7740 8439 D LeakCanary: ╰→ com.navercorp.nid.oauth.activity.NidOAuthCustomTabActivity instance
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ Leaking: YES (ObjectWatcher was watching this because com.navercorp.nid.oauth.activity.NidOAuthCustomTabActivity
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ received Activity#onDestroy() callback and Activity#mDestroyed is true)
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ Retaining 13.0 kB in 298 objects
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ key = 420dea8d-ab16-485f-b0d2-e76a50b54f3b
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ watchDurationMillis = 5729
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ retainedDurationMillis = 714
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ mApplication instance of com.linecorp.b612.android.B612Application
10-31 11:13:33.132 7740 8439 D LeakCanary: ​ mBase instance of androidx.appcompat.view.ContextThemeWrapper

[case2]
10-31 11:13:33.132 7740 8439 D LeakCanary: 6189 bytes retained by leaking objects
10-31 11:13:33.132 7740 8439 D LeakCanary: Signature: b6c624749dfa6c1af2a77dfec7c9a186019e9cf7
10-31 11:13:33.132 7740 8439 D LeakCanary: ┬───
10-31 11:13:33.132 7740 8439 D LeakCanary: │ GC Root: System class
10-31 11:13:33.132 7740 8439 D LeakCanary: │
10-31 11:13:33.132 7740 8439 D LeakCanary: ├─ android.app.ActivityThread class
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Leaking: NO (a class is never leaking)
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ↓ static ActivityThread.sCurrentActivityThread
10-31 11:13:33.132 7740 8439 D LeakCanary: │ ~~~~~~~~~~~~~~~~~~~~~~
10-31 11:13:33.132 7740 8439 D LeakCanary: ├─ android.app.ActivityThread instance
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Leaking: UNKNOWN
10-31 11:13:33.132 7740 8439 D LeakCanary: │ Retaining 32.1 kB in 678 objects
10-31 11:13:33.132 7740 8439 D LeakCanary: │ mInitialApplication instance of com.linecorp.b612.android.B612Application
10-31 11:13:33.133 7740 8439 D LeakCanary: │ mSystemContext instance of android.app.ContextImpl
10-31 11:13:33.133 7740 8439 D LeakCanary: │ mSystemUiContext instance of android.app.ContextImpl
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ↓ ActivityThread.mLastResumedActivity
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ~~~~~~~~~~~~~~~~~~~~
10-31 11:13:33.133 7740 8439 D LeakCanary: ├─ android.app.ActivityThread$ActivityClientRecord instance
10-31 11:13:33.133 7740 8439 D LeakCanary: │ Leaking: UNKNOWN
10-31 11:13:33.133 7740 8439 D LeakCanary: │ Retaining 60.3 kB in 1060 objects
10-31 11:13:33.133 7740 8439 D LeakCanary: │ activity instance of com.linecorp.b612.android.sns.NaverLinkActivity with mDestroyed = false
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ↓ ActivityThread$ActivityClientRecord.nextIdle
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ~~~~~~~~
10-31 11:13:33.133 7740 8439 D LeakCanary: ├─ android.app.ActivityThread$ActivityClientRecord instance
10-31 11:13:33.133 7740 8439 D LeakCanary: │ Leaking: UNKNOWN
10-31 11:13:33.133 7740 8439 D LeakCanary: │ Retaining 59.1 kB in 1038 objects
10-31 11:13:33.133 7740 8439 D LeakCanary: │ activity instance of com.navercorp.nid.oauth.NidOAuthBridgeActivity with mDestroyed = true
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ↓ ActivityThread$ActivityClientRecord.activity
10-31 11:13:33.133 7740 8439 D LeakCanary: │ ~~~~~~~~
10-31 11:13:33.133 7740 8439 D LeakCanary: ╰→ com.navercorp.nid.oauth.NidOAuthBridgeActivity instance
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ Leaking: YES (ObjectWatcher was watching this because com.navercorp.nid.oauth.NidOAuthBridgeActivity received
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ Activity#onDestroy() callback and Activity#mDestroyed is true)
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ Retaining 6.2 kB in 208 objects
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ key = 362697ea-e281-42d3-a0ac-f92e14c14c1d
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ watchDurationMillis = 5750
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ retainedDurationMillis = 748
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ mApplication instance of com.linecorp.b612.android.B612Application
10-31 11:13:33.133 7740 8439 D LeakCanary: ​ mBase instance of androidx.appcompat.view.ContextThemeWrapper

유저 프로필 API 요청시 age, gender 등이 null로 내려오는 이슈

2022.09.14 에 해당 API로 요청했을 때는 age, gender 등의 value를 받아볼 수 있었습니다.
2022.09.16 에 동일하게 요청했을 때 age, gender, profileImage 등이 null로 내려옵니다.
id 같은 경우에도 형식이 변경된 것 같은데요. (기존 : 숫자 -> 변경: 영대소문자 + 숫자).
API response 부분에 수정이 있나요?

SDK 버전 4.2.6 과 5.1.1 에서 동일하게 발생합니다.

2022.09.14 응답 예시 (IDE 캡쳐, v4.2.6, v 5.1.1)
image
image

2022.09.16 응답 예시 (v4.2.6, v 5.1.1)

  • <?xml version=“1.0” encoding=“UTF-8" ?><data><result><resultcode>00</resultcode><message>success</message></result><response><id><![CDATA[rfCIIF1dXWbdS8TiA1Dg*********************]]></id><email><![CDATA[[email protected]]]></email><name><![CDATA[장서정]]></name></response></data>
  • NidProfileResponse
    resultCode=00
    message=success
    profile=NidProfile
    • id=rfCIIF1dXWbdS8TiA1Dg*******************
    • nickname=null
    • name=장서정
    • email=jsj947@naver.com
    • gender=null
    • age=null
    • birthday=null
    • profileImage=null
    • birthYear=null
    • mobile=null

kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized

앱실행 후 네이버 로그인 클릭, 그 후 호출 어플리케이션의 인스턴스가 파괴되면 크래시가 발생합니다.

아래는 샘플앱으로 재현하였지만 실사용중인 프로덕트 앱에서도 현재 발생하고 있습니다.

샘플앱 기동 -> 네이버 로그인 클릭 -> 인앱브라우저 호출(웹뷰) -> 홈버튼으로 onPause
adb shell am kill com.navercorp.nid.oauth.sample -> onResume -> back press -> crash

com.navercorp.nid.oauth.sample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.navercorp.nid.oauth.sample, PID: 5560
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.navercorp.nid.oauth.sample/com.navercorp.nid.oauth.NidOAuthBridgeActivity}: kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4035)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.app.ActivityThread.main(ActivityThread.java:8663)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
        at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:33)
        at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:16)
        at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:28)
        at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:27)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:27)
        at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:84)
        at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getClientId(NidOAuthPreferencesManager.kt:53)
        at com.navercorp.nid.oauth.NidOAuthBridgeActivity.initData(NidOAuthBridgeActivity.kt:45)
        at com.navercorp.nid.oauth.NidOAuthBridgeActivity.onCreate(NidOAuthBridgeActivity.kt:75)
        at android.app.Activity.performCreate(Activity.java:8290)
        at android.app.Activity.performCreate(Activity.java:8270)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4009)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:226) 
        at android.os.Looper.loop(Looper.java:313) 
        at android.app.ActivityThread.main(ActivityThread.java:8663) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 

네이버 아이디로 로그인 중입니다. 무한 프로그레스

네이버 아이디로 로그인 중입니다. 다이얼로그바가 사라지지않습니다.
mOAuthLoginInstance.startOauthLoginActivity(mActivity, mOAuthLoginHandler);
호출 후 해당 핸들러 내부 run 메소드 안쪽에서
RequestApiTask 를 호출합니다.

OAuthLogin Class 내부의 OAuthLoginTask 와 충돌을 일으키는게 아닐까요?

initialize 후 authenticate 호출하는데 오류가 발생합니다.

authenticate 내부 코드에서 Intent를 요청할때 FLAG가 설정이 안되어 있는지 System.err 이 발생합니다.

/**
 * OAuth 2.0 로그인을 수행한다.
 *
 * RefreshToken이 존재하는 경우, 이미 연동이 된 것이므로 AccessToken을 갱신해준다.
 *
 * @param context authenticate 메서드를 호출한 Activity의 Context
 * @param callback 결과값을 받을 콜백
 */
fun authenticate(context: Context, callback: OAuthLoginCallback) {
    if (getState() == NidOAuthLoginState.NEED_INIT) {
        Toast.makeText(context.applicationContext, "SDK 초기화가 필요합니다.", Toast.LENGTH_SHORT).show()
        return
    }

    oauthLoginCallback = callback

    val refreshToken = getRefreshToken()
    if (refreshToken.isNullOrEmpty()) {
        val intent = Intent(context, NidOAuthBridgeActivity::class.java)
        val orientation = context.resources.configuration.orientation
        intent.putExtra("orientation", orientation)
        context.startActivity(intent)
    } else {
        NidOAuthLogin().refreshToken(context, callback)
    }
}

오류 로그는 다음과 같습니다.

2022-02-10 19:13:44.271 23234-25141/com.example.naverlogin W/System.err: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.app.ContextImpl.startActivity(ContextImpl.java:995)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.app.ContextImpl.startActivity(ContextImpl.java:971)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.content.ContextWrapper.startActivity(ContextWrapper.java:389)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at com.navercorp.nid.NaverIdLoginSDK.authenticate(NaverIdLoginSDK.kt:102)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at com.sortielab.sumstation.MainActivity.startNaverLogin(MainActivity.kt:156)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at com.sortielab.sumstation.SumStationBridge.requestNaverLogin(SumStationBridge.kt:111)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.os.MessageQueue.nativePollOnce(Native Method)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.os.MessageQueue.next(MessageQueue.java:336)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.os.Looper.loop(Looper.java:197)
2022-02-10 19:13:44.271 23234-25141/com.sortielab.sumstation W/System.err: at android.os.HandlerThread.run(HandlerThread.java:67)

android.util.AndroidRuntimeException: requestFeature() must be called before adding content

Caused by android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.PhoneWindow.requestFeature(PhoneWindow.java:396)
at android.app.Activity.requestWindowFeature(Activity.java:5110)
at com.navercorp.nid.oauth.activity.NidOAuthWebViewActivity.onCreate(NidOAuthWebViewActivity.kt:67)
at android.app.Activity.performCreate(Activity.java:8071)
at android.app.Activity.performCreate(Activity.java:8051)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1330)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3629)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2211)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7952)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

5.1.1 버전에서 발생, NidOAuthWebViewActivity 67line 에서 문제가 발생하고 있습니다.

NaverIdLoginSDK.initialize 초기화 오류

NaverIdLoginSDK.initialize(context, {OAUTH_CLIENT_ID}, {OAUTH_CLIENT_SECRET}, {OAUTH_CLIENT_NAME})
초기화 호출 시 NidLog 관련 lateinit property instance has not been initialized 발생합니다.

fun init() {
    instance = if (BuildConfig.BUILD_TYPE.equals("debug", ignoreCase = true)) {
        DebugNidLog()
    } else {
        ReleaseNidLog()
    }
}

NidLog에서 init 부분이 호출 안되는 것 같습니다.

로그인 시도 시 user_cancel 반환

안드로이드 네아로 5.0.1버전 사용중입니다.

기본 앱 브라우저를 삼성에서 크롬으로 바꾸고 로그인을 시도,

이메일 제공 동의 화면에서 확인을 클릭하면 user_cancel 메세지가 반환됩니다.

구글링해보니 4.2.6에서 fix된 걸로 나와있던데..

그리고 여러 기기에서 테스트해봤는데 특정 기기에서만 발생합니다. 해당 기기 안드로이드 9버전 사용중입니다

Proguard 설정 공식문서 등록 요청

공식문서에 Android 버전 구현시 릴리즈 버전에서 Proguard 에 난독화 제외 설정 방법이 없네요.
검색으로 알아보니

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

대부분의 모든 블로그가 위와같이 설정을 요청하지만 패키지명 변경으로 아래와 같이 설정해줘야하는데

-keep public class com.navercorp.nid.** {
public *;
}

이부분에 대해 공식문서에 등록좀 해주세요....한참 헤맸습니다..

빌드 설정 문의

안녕하세요.

네아로 5.0.1을 적용 중입니다.
작업 중 몇가지 문의 사항이 있습니다.

  1. 개발자 사이트의 document에서는 gradle에 oauth-5.0.0.aar 라이브러리를 등록하여 사용하는 방법으로 안내가 되고 있습니다만,
    실제 github에서 다운받은 샘플 소스코드는 어째서, Nid-OAuth 프로젝트를 포함시켜서 동작하는 것으로 되어 있는 것인가요?

  2. 개발자 다큐먼트에 설명되어 있는 oauth-5.0.0.aar 파일은 어디에서 찾을 수 있는 건가요?
    샘플 프로젝트를 빌드해도 해당 파일을 찾을 수 없습니다.

  3. 또한, 다큐먼트에서는 kotlin 과 java에 대해서 함께 설명되고 있지만, 샘플 코드는 only kotlin으로만 되어 있습니다.

java 샘플프로젝트는 준비가 안된 것인지요?

확인 부탁 드립니다.
수고하세요.

Manifest merger failed : Apps targeting Android 12 - Android Studio Error

My android project target sdk upgrade to 31, and discover this problem,

and I found this problem in latest version 4.2.6

<activity
            android:name="com.nhn.android.naverlogin.ui.OAuthCustomTabActivity"
            android:configChanges="orientation|screenSize"
            android:launchMode="singleTask"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <!-- Intent URL 에서 로그인 액티비티를 실행하기 위해 설정 -->
                <data
                    android:host="authorize"
                    android:path="/"
                    android:scheme="naver3rdpartylogin" />
            </intent-filter>
        </activity>

I think it need to add android :exported=true in activity.

ACTIVITY_IS_SINGLE_VIEW error when login by chrome from activity with locked screen orientation

After adding SDK to our game where screen orientation is locked to landscape we have found that after first login there is an error callback with activity_is_single_task code. An error could be reproduced to sample project in this repo.

Steps to reproduce

  1. Lock screenOrientation to landscape for OAuthSampleActivity in manifest
  2. Use phone with portrait orientation without Naver app
  3. Login to app first time (to see confirmation window)

An error activity_is_single_task will be occurred

Bug could be fixed by adding configChanges=“screenSize|orientation” to com.nhn.android.naverlogin.ui.OAuthLoginActivity. We added it to our top manifest for workaround.

com.google.crypto.tink.shaded.protobuf.c0: Protocol message contained an invalid tag (zero)

  • SDK 5.2.0

다음과 같은 issue가 발생합니다.

com.navercorp.nid.NaverIdLoginSDK.getLastErrorCode(NaverIdLoginSDK.kt:148) 를 부를 때 입니다.

주 원인은 issue 로 보이며, 해당 Exception이 발생한 경우 EncryptedSharedPreferences의 초기화에서 파일 이름을 변경해주는 로직을 넣어야 할 것 같습니다.

아니면 jetpack security 쪽의 업데이트를 기다려야 할 것 같습니다.

Caused by com.google.crypto.tink.shaded.protobuf.c0: Protocol message contained an invalid tag (zero).
       at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1566)
       at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1663)
       at com.google.crypto.tink.proto.Keyset.parseFrom(Keyset.java:957)
       at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read(SharedPrefKeysetReader.java:84)
       at com.google.crypto.tink.CleartextKeysetHandle.read(CleartextKeysetHandle.java:58)
       at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:328)
       at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
       at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
       at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
       at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)
       at com.navercorp.nid.oauth.EncryptedPreferences.init(EncryptedPreferences.kt:34)
       at com.navercorp.nid.oauth.EncryptedPreferences.access$init(EncryptedPreferences.kt:17)
       at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:30)
       at com.navercorp.nid.oauth.EncryptedPreferences$encryptedPreferences$2.invoke(EncryptedPreferences.kt:29)
       at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
       at com.navercorp.nid.oauth.EncryptedPreferences.getEncryptedPreferences(EncryptedPreferences.kt:29)
       at com.navercorp.nid.oauth.EncryptedPreferences.get(EncryptedPreferences.kt:86)
       at com.navercorp.nid.oauth.NidOAuthPreferencesManager.getLastErrorCode(NidOAuthPreferencesManager.kt:84)
       at com.navercorp.nid.NaverIdLoginSDK.getLastErrorCode(NaverIdLoginSDK.kt:148)
       at com.dooboolab.naverlogin.RNNaverLoginModule$Companion.createLoginFailureResponse(RNNaverLoginModule.kt:143)
       at com.dooboolab.naverlogin.RNNaverLoginModule$Companion.onLoginFailure(RNNaverLoginModule.kt:125)
       at com.dooboolab.naverlogin.RNNaverLoginModule$Companion.access$onLoginFailure(RNNaverLoginModule.kt:101)
       at com.dooboolab.naverlogin.RNNaverLoginModule.login$lambda-1(RNNaverLoginModule.kt:88)
       at com.dooboolab.naverlogin.RNNaverLoginModule.$r8$lambda$9DhD-bSQORgiqNoOhxh4y3p9nl8(RNNaverLoginModule.kt)
       at com.dooboolab.naverlogin.RNNaverLoginModule$$InternalSyntheticLambda$0$dc93727e2d141454a50d11f5e02e4f0b65846d86912d8151f7fbbf5793324763$0.run(RNNaverLoginModule.java:10)
       at android.os.Handler.handleCallback(Handler.java:938)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7882)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:558)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009)

네아로 WebView 방식 호출시 타이틀: OAuth2.0 by WebView

Screenshot_20220218_162638

단말: 갤럭시 S21
OS: Android 12
release 빌드에서 네아로 WebView 방식 호출시 타이틀이 이렇게 나오고 있습니다.: OAuth2.0 by WebView
"네이버 아이디 로그인" 이런 표현이 나올거로 예상했는데, 정상적인 화면인지 문의 드립니다.

kotlin.UninitializedPropertyAccessException 에러

NidOAuthBridgeActivity.onActivityResult() 에서
data가 null 인경우, NaverIdLoginSDK.oauthLoginCallback 이 초기화 되지 않아 에러가 발생합니다.
재현은 해볼려고 하는데 잘 되지 않네요.

Caused by kotlin.UninitializedPropertyAccessException: lateinit property oauthLoginCallback has not been initialized
       at com.navercorp.nid.NaverIdLoginSDK.getOauthLoginCallback(NaverIdLoginSDK.kt:39)
       at com.navercorp.nid.oauth.NidOAuthBridgeActivity.oauthFinish(NidOAuthBridgeActivity.kt:269)
       at com.navercorp.nid.oauth.NidOAuthBridgeActivity.finishWithErrorResult(NidOAuthBridgeActivity.kt:260)
       at com.navercorp.nid.oauth.NidOAuthBridgeActivity.onActivityResult(NidOAuthBridgeActivity.kt:284)
       at android.app.Activity.dispatchActivityResult(Activity.java:8550)
       at android.app.ActivityThread.deliverResults(ActivityThread.java:5583)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4905)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4955)
       at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:246)
       at android.app.ActivityThread.main(ActivityThread.java:8653)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

Non Activity class 에서 NaverIdLoginSDK.authenticate 호출시 exception

Non Activity class 에서 NaverIdLoginSDK.authenticate 호출시 exception 발생합니다.
해당 Activity 에 FLAG_ACTIVITY_NEW_TASK flag 추가 요청 드립니다.

    android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
        at android.app.ContextImpl.startActivity(ContextImpl.java:1131)
        at android.app.ContextImpl.startActivity(ContextImpl.java:1107)
        at android.content.ContextWrapper.startActivity(ContextWrapper.java:420)
        at com.navercorp.nid.NaverIdLoginSDK.authenticate(NaverIdLoginSDK.kt:102)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.