Android: OpenID инициализирует AuthState как аутентифицированный при сборке выпуска?

#android #oauth-2.0 #openid #android-jetpack-compose

Вопрос:

У меня действительно странная проблема со release сборкой моего приложения. Он использует net.openid:appauth:0.7.1 библиотеку и хранит AuthState внутри DataStore ( androidx.datastore:datastore-preferences:1.0.0-alpha06 ). Вот onCreate метод моей основной деятельности:

 override fun onCreate(savedInstanceState: Bundle?) {  super.onCreate(savedInstanceState)  setContent {  val authState by authViewModel.authStateFlow.collectAsState(null)  AppTheme {  Surface(color = MaterialTheme.colors.background) {  when (authState?.isAuthorized) {  true -gt; {  App(authViewModel::onLogoutEvent)  }  false -gt; AuthScreen { authViewModel.onLoginEvent(authPageLauncher) }  null -gt; {}  }  }  }  } }  

Здесь приложение решает, на основе AuthState.isAuthorized какого экрана показывать. authViewModel берет эти данные из другого источника:

 @HiltViewModel class AuthViewModel @Inject constructor(  private val authStateStorage: AuthStateStorage,  private val authService: AuthorizationService,  private val usersRepo: UsersRepository,  private val notificationsRepo: NotificationsRepository ) : ViewModel() {   val authStateFlow = authStateStorage.authStateFlow  // ... }  

Та часть AuthStateStorage , которая отвечает за это:

 class AuthStateStorage(context: Context) {  private companion object {  const val AUTH_STATE_PREFS_NAME = "auth_state_prefs"  val AUTH_STATE_KEY = stringPreferencesKey("auth_state_key")  val USER_ID_KEY = stringPreferencesKey("user_id_key")  val USER_PAYLOAD_KEY = stringPreferencesKey("user_payload_key")  }   private val dataStore = context.createDataStore(AUTH_STATE_PREFS_NAME)   private fun Preferences.getAuthState() = this[AUTH_STATE_KEY]?.let {  AuthState.jsonDeserialize(it)  } ?: AuthState()   val authStateFlow = dataStore.data.map { it.getAuthState() }  // ... }  

Можно было бы подумать , что dataStore будет храниться вновь созданный экземпляр AuthState , чей isAuthorized файл находится false . И это верно для debug сборок.

Но когда я создаю release apk и устанавливаю его, App составляемый файл немедленно вызывается, вызывая исключение. У меня также есть перехватчик токенов, который я подключаю к своему клиенту OHTTP:

 class TokenInterceptor @Inject constructor(  private val authStateStorage: AuthStateStorage,  private val authService: AuthorizationService ): Interceptor {  private companion object {  const val TAG = "TokenInterceptor"  const val AUTH_HEADER = "Authorization"  }   override fun intercept(chain: Interceptor.Chain): Response {  var request = chain.request()  request.header(AUTH_HEADER) ?: run {  request = chain.request()  .newBuilder()  .addHeader(AUTH_HEADER, "Bearer ${getAccessToken()}")  .build()  }  return chain.proceed(request)  }   private fun getAccessToken(): String = runBlocking {  val authState = authStateStorage.authStateFlow.first()  val isNeedToUpdateToken = authState.needsTokenRefresh   suspendCoroutine { continuation -gt;  authState.performActionWithFreshTokens(authService) { accessToken, _, exception -gt;  exception?.let {  /*  Exception occurs here  */  Log.e(TAG, "Exception in token process: ", it)  continuation.resumeWithException(it)  } ?: run {  if (isNeedToUpdateToken) {  runBlocking {  authStateStorage.updateAuthState(authState)  }  }  continuation.resume(accessToken!!)  }  }  }  } }  

Exception text is pretty expected:

 E/TokenInterceptor: Exception in token process:   AuthorizationException: {"type":2,"code":2002,"error":"invalid_grant","errorUri":""}  at net.openid.appauth.AuthorizationService$TokenRequestTask.onPostExecute(AuthorizationService.java:480)  at net.openid.appauth.AuthorizationService$TokenRequestTask.onPostExecute(AuthorizationService.java:395)  at android.os.AsyncTask.finish(AsyncTask.java:771)  at android.os.AsyncTask.access$900(AsyncTask.java:199)  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:223)  at android.app.ActivityThread.main(ActivityThread.java:7656)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)  

Таким образом, в основном release приложение полностью пропускает (или пропускает) проверку состояния аутентификации, а затем переходит к выполнению HTTP-запросов, как будто ничего не случилось. Но самое странное заключается в том, что если я только что установил release сборку без ее запуска, перейдите в раздел Информация о приложении -gt; Хранилище и кэш -gt;gt; Очистить хранилищеgt;gt;, а затем запустите мое приложение, оно будет вести себя так, как задумано. Я не смог объяснить и исправить это поведение. Есть какие-нибудь идеи?