Skip to content

Commit

Permalink
#86 feat : BearerInterceptor 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
yy0ung committed Nov 23, 2023
1 parent cc0ea52 commit 27c1578
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Aos/.idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.avengers.nibobnebob.app.di

import android.content.Context
import com.avengers.nibobnebob.BuildConfig
import com.avengers.nibobnebob.app.DataStoreManager
import com.avengers.nibobnebob.config.AccessTokenInterceptor
import com.avengers.nibobnebob.config.BearerInterceptor
import com.avengers.nibobnebob.presentation.util.Constants.BASE_URL
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
Expand All @@ -23,7 +26,7 @@ object NetworkModule {
httpLoggingInterceptor: HttpLoggingInterceptor,
accessTokenInterceptor: AccessTokenInterceptor,
bearerInterceptor: BearerInterceptor
) : OkHttpClient {
): OkHttpClient {

return OkHttpClient.Builder()
.readTimeout(3000, TimeUnit.MILLISECONDS)
Expand All @@ -37,10 +40,19 @@ object NetworkModule {
@Provides
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().apply {
level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
}
}

@Provides
fun provideAccessTokenInterceptor(dataStoreManager: DataStoreManager): AccessTokenInterceptor =
AccessTokenInterceptor(dataStoreManager)

@Provides
fun provideBearerInterceptor(dataStoreManager: DataStoreManager): BearerInterceptor =
BearerInterceptor(dataStoreManager)

@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {

Expand All @@ -51,5 +63,5 @@ object NetworkModule {
.build()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.util.Log
import com.avengers.nibobnebob.app.DataStoreManager
import com.avengers.nibobnebob.presentation.util.Constants.ACCESS
import com.avengers.nibobnebob.presentation.util.Constants.AUTHORIZATION
import com.avengers.nibobnebob.presentation.util.Constants.BEARER
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
Expand All @@ -24,7 +25,7 @@ class AccessTokenInterceptor @Inject constructor(private val dataStoreManager: D
Log.d("토큰 테스트",accessToken.toString())
val builder: Request.Builder = chain.request().newBuilder()
accessToken.let {
builder.addHeader(AUTHORIZATION,"$ACCESS $accessToken")
builder.addHeader(AUTHORIZATION,"$BEARER $accessToken")
}
return chain.proceed(builder.build())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,88 @@
package com.avengers.nibobnebob.config


import com.avengers.nibobnebob.app.DataStoreManager
import com.avengers.nibobnebob.data.model.BaseState
import com.avengers.nibobnebob.data.model.request.RefreshTokenRequest
import com.avengers.nibobnebob.data.model.response.BaseResponse
import com.avengers.nibobnebob.data.model.response.NaverLoginResponse
import com.avengers.nibobnebob.data.model.runRemote
import com.avengers.nibobnebob.data.remote.RefreshApi
import com.avengers.nibobnebob.presentation.util.Constants
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import javax.inject.Inject

class BearerInterceptor @Inject constructor() : Interceptor {
class BearerInterceptor @Inject constructor(
private val dataStoreManager: DataStoreManager
) : Interceptor {

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {

val originalRequest = chain.request()
val response = chain.proceed(originalRequest)

// runBlocking {
// 로컬에 refreshToken이 있다면
// sharedPreferences.getString(X_REFRESH_TOKEN, null)?.let { refresh ->
// Log.d(TAG, refresh)
// // refresh API 호출
// val result = Retrofit.Builder()
// .baseUrl(BASE_DEV_URL)
// .addConverterFactory(GsonConverterFactory.create())
// .build()
// .create(RefreshAPI::class.java).refreshToken(refresh)
//
// if (result.isSuccessful) {
// Log.d(TAG,"리프래시 성공")
// result.body()?.let { body ->
// Log.d(TAG,body.accessToken)
// // refresh 성공시 로컬에 저장
// sharedPreferences.edit()
// .putString(X_ACCESS_TOKEN, body.accessToken)
// .putString(X_REFRESH_TOKEN, body.refreshToken)
// .apply()
//
// isRefreshed = true
// accessToken = body.accessToken
// }
// }else{
// val error =
// Gson().fromJson(result.errorBody()?.string(), ErrorResponse::class.java)
// Log.d(TAG,error.message)
// }
// }
// }
//
// if (isRefreshed) {
//
// // 기존 API 재호출
// val newRequest = originalRequest.newBuilder()
// .addHeader("Authorization", accessToken)
// .build()
//
// return chain.proceed(newRequest)
// }
// 해당 특정 에러코드가 그대로 내려간다면, 세션 만료 처리
var newAccessToken: String? = null

if (response.code == TOKEN_ERROR) {
runBlocking {
val refreshToken = dataStoreManager.getRefreshToken().first()
refreshToken?.let { token ->
when (val result = getNewAccessToken(token)) {
is BaseState.Success -> {
response.close()
newAccessToken = result.data.body.accessToken
newAccessToken?.let {
dataStoreManager.putAccessToken(newAccessToken!!)
}
}

else -> {
dataStoreManager.deleteAccessToken()
dataStoreManager.deleteRefreshToken()
}
}
}
}
(newAccessToken)?.let {
val newRequest = originalRequest.newBuilder()
.addHeader(AUTHORIZATION, "$BEARER $newAccessToken")
.build()
return chain.proceed(newRequest)
}
}

return response
}


private suspend fun getNewAccessToken(refreshToken: String?): BaseState<BaseResponse<NaverLoginResponse>> {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
val okHttpClient = OkHttpClient.Builder().addInterceptor(loggingInterceptor).build()

val retrofit = Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
val api = retrofit.create(RefreshApi::class.java)
return runRemote { api.refreshToken(RefreshTokenRequest(refreshToken)) }
}

companion object {
const val TOKEN_ERROR = 401
const val AUTHORIZATION = "Authorization"
const val BEARER = "Bearer"
}
}


0 comments on commit 27c1578

Please sign in to comment.