morristech
3/8/2019 - 5:37 AM

Get rest api with Auth - token and using okhttp Authenticator to manage the refresh token

Get rest api with Auth - token and using okhttp Authenticator to manage the refresh token

object RetrofitGetAPIWithAuth {
    private val BASE_URL = BuildConfig.API_BASE
    private var retrofit: Retrofit? = null
    private val tokenLoginModel: TokenLoginModel? = obtainTokenLoginModel()
    private val accessToken = tokenLoginModel?.access_token

    class HeaderInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            var request = chain.request()
            request = request.newBuilder()
                    .addHeader("Authorization", "Bearer " + accessToken)
                    .build()
            return chain.proceed(request)
        }
    }
    
    private val okHttpClient = OkHttpClient().newBuilder()
           .addInterceptor(HeaderInterceptor()).authenticator(TokenAuthenticator())
            .build()

    val retrofitClient: Retrofit?
        get() {
            if (retrofit == null) {
                retrofit = Retrofit.Builder()
                        .client(okHttpClient)
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build()
            }
            return retrofit
        }
}
class TokenAuthenticator : Authenticator {
    override fun authenticate(route: Route?, response: Response?): Request? {
        val tokenLoginModel: TokenLoginModel? = obtainTokenLoginModel()

        val apiService = RetrofitLogin.client!!.create(ApiInterface::class.java)

        val newAccessToken: String?  = apiService.refreshToken(BuildConfig.GRANT_TYPE_LOGIN, BuildConfig.CLIENT_ID_LOGIN,
                tokenLoginModel?.access_token, tokenLoginModel?.refresh_token, 20.toString()).execute().body()?.access_token.toString()
       // Add new header to rejected request and retry it
        return response?.request()?.newBuilder()?.header("Authorization", newAccessToken)?.build()
    }
}

fun obtainTokenLoginModel(): TokenLoginModel? {
    val fooRawTk: Any? = SharedPreferencesHelper().load(Constants.SHARED_PREFS_AUTH_TOKEN)
    return CryptoHelp().decrypt(fooRawTk.toString())
}