Повторно выполнить запрос веб-службы после обновления токена с помощью модернизации в перехватчике - PullRequest
0 голосов
/ 14 июля 2020

У меня есть приложение Android с модифицированным клиентом и перехватчиком, которое проверяет код ответа 401 (срок действия токена истек), поэтому после обнаружения этой ошибки я могу выполнить другую веб-службу, которая обновит sh мой токен, используя токен refre sh, предоставленный мне, когда я вошел в систему, и все это работает хорошо и плавно.

Моя проблема в том, как отозвать первый запрос после получения нового действительного токена и его сохранения.

 class AuthenticationInterceptorRefreshToken(var client: OkHttpClient?, var retrofit: Retrofit?) :
    Interceptor {
    private val TAG = "AuthenticationIntercept"
    var authenticationUseCase = AuthenticationUseCase()

    @SuppressLint("CheckResult")
    override fun intercept(chain: Interceptor.Chain): Response {
        var request = chain.request()
        val builder = request.newBuilder()
        request = builder.build()
        val response = chain.proceed(request)
        if (response.code() == 401) {
            Log.e(TAG, "intercept: Refresh it")
            if (Paper.book().contains(Const.USER_CONNECTED)) {
                val currentToken: String =
                    (Paper.book().read(Const.USER_CONNECTED) as LoginResponse).refreshToken
                authenticationUseCase.refreshToken(RefreshTokenRequest(currentToken))
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            when (it) {
                                is AuthenticationUseCase.LoginResult.Success -> {
                                    val new =
                                        (Paper.book().read(Const.USER_CONNECTED) as LoginResponse)
                                    val gson = Gson()
                                    val data = gson.fromJson(
                                        gson.toJson(it.userResponse.data),
                                        NewTokenResponse::class.java
                                    )
                                    new.token = data.token
                                    Paper.book().write(Const.USER_CONNECTED, new)
                                    Log.e(TAG, "handleRefreshToken Success New: $new")
                                    //todo re-execute the web service
                                }
                                is AuthenticationUseCase.LoginResult.Failure -> {
                                    Log.e(
                                        TAG,
                                        "handleRefreshToken Failure: ${it.throwable.localizedMessage}"
                                    )
                                    logout()
                                }
                            }

                        }, {
                            Log.e(TAG, "intercept: Here something BAD: $it")
                        })
                return response
            } else {
                Log.e(TAG, "intercept No data found: ")
                context.startActivity(
                    Intent(
                        context,
                        WelcomingActivity::class.java
                    ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                )
            }
            return response
        }
        return response
    }


    @SuppressLint("CheckResult")
    private fun logout() {
        authenticationUseCase.logout(
            LogoutRequest(
                (Paper.book().read(Const.USER_CONNECTED) as LoginResponse).user.id,
                (Paper.book().read(Const.USER_CONNECTED) as LoginResponse).refreshToken
            )
        ).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                when (it) {
                    is AuthenticationUseCase.LoginResult.Success -> {
                        Log.e(TAG, "showLogoutDialog: Success: ${it.userResponse}")
                        Paper.book().delete(Const.USER_CONNECTED)
                        GlobalUtils.navigateToActivity(
                            context as Activity,
                            context,
                            WelcomingActivity::class.java
                        )
                    }
                    is AuthenticationUseCase.LoginResult.Failure -> {
                        if (it.throwable.localizedMessage.contains("500")) {
                            Log.e(TAG, "getConnectedUser: Problem here 2")
                            Toast.makeText(context, "Server error...", Toast.LENGTH_LONG)
                                .show()
                        }
                        Log.e(TAG, "showLogoutDialog: Failure:  ${it.throwable}")
                    }
                }
            }
    }
}

И это мой модифицированный клиент, который я использую при каждом обращении к серверу

object RetrofitClient {
    private var retrofit: Retrofit? = null
    private var client: OkHttpClient? = null
    fun build(): ItchekApi {
        if (retrofit == null) {
            if (client == null)
                client = OkHttpClient.Builder()
                    .addInterceptor(
                        AuthenticationInterceptorRefreshToken(
                            client,
                            retrofit
                        )
                    )
                    .addInterceptor(HeaderInterceptor())
                    .connectTimeout(100, TimeUnit.SECONDS)
                    .readTimeout(100, TimeUnit.SECONDS)
                    .writeTimeout(100, TimeUnit.SECONDS)
                    .build()

            retrofit = Retrofit.Builder()
                .client(client)
//                .addConverterFactory(NullOnEmptyConverterFactory())
                .baseUrl(ApiEndPoints.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
                .build()
        }
        return retrofit!!.create(ItchekApi::class.java)
    }
}

1 Ответ

0 голосов
/ 16 июля 2020

У вас есть новый токен доступа, теперь вам нужно создать новый запрос с новым токеном доступа

Замените свой //todo re-execute the web service на этот

if (new.token != null) {
   val newRequest = chain.request().newBuilder()
                    .addHeader("Authorization", new.token)
                    .build()
   return chain.proceed(newRequest)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...