Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
90b9ba0
[feat] 토큰 작업 중
kangyuri1114 Apr 16, 2025
80521ce
[feat] TokenAuthenticator hilt provide 로직으로 수정
kangyuri1114 Apr 17, 2025
54ae6f7
[feat] Fragment @AndroidEntryPoint 추가
kangyuri1114 Apr 17, 2025
ce2014c
[feat] 로그인 에러 토스트 메시지 줄바꿈 삭제
kangyuri1114 Apr 17, 2025
9ae0b78
[feat] oauthService 주입 방식 수정
kangyuri1114 Apr 17, 2025
7f71442
[feat] 토큰이 있는 경우와 없는 경우의 retrofit, okhttp 분리
kangyuri1114 Apr 17, 2025
e404ac4
[feat] 디버깅 okhttp에 authenticator 추가, 백그라운드 환경에서 toast 사용하도록 공통 클래스 추가…
kangyuri1114 Apr 17, 2025
6b14144
[feat] LogoutUseCase 수정
kangyuri1114 Apr 17, 2025
78100a8
[feat] 불필요 파일 및 코드 삭제
kangyuri1114 Apr 18, 2025
6f84fdd
[feat] @Named 어노테이션 @Qualifier 로 변경
kangyuri1114 Apr 18, 2025
36b671c
[feat] 토큰 재발급 로직을 ReissueTokenUseCase 사용하도록 수정
kangyuri1114 Apr 18, 2025
057c7c9
[feat] 불필요 임포트 삭제
kangyuri1114 Apr 18, 2025
d9bd354
[feat] LogoutUseCase 및 사용 화면 코드 복구
kangyuri1114 Apr 18, 2025
ec138da
[feat] 임시커밋
kangyuri1114 Apr 24, 2025
628c458
feat: 토큰뷰모델 도입, baseActivity에서 토큰 뷰모델 감지 로직으로 수정
kangyuri1114 Apr 24, 2025
6f327c8
[feat] 임시커밋
kangyuri1114 Apr 25, 2025
21e8df0
feat: 토큰이벤트버스 도입 및 전체적인 토큰 갱신 구조 변경 완료
kangyuri1114 Apr 26, 2025
0022ba5
feat: ShowToastSafely 삭제
kangyuri1114 Apr 26, 2025
7e4ec17
feat: 불필요한 import 삭제
kangyuri1114 Apr 26, 2025
7801fe4
feat: AuthUtil 삭제
kangyuri1114 Apr 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 133 additions & 133 deletions app/src/main/java/com/eatssu/android/data/RetrofitImpl.kt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 RetrofitImpl.kt 없앨 순 없을까요? 이게 레거시 레트로핏이라서... 혹시 아직 의존성이 있어서 못지운건가요? (제가 안지운 이유는 의존성이 있어서 못지운거라서)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아뇨! 얘도 지워도 되냐고 물어보려고 했는데 까먹었었어요
지우겠씁니다!

Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,6 @@ object RetrofitImpl {
.build()
}

// 토큰 없는 Retrofit
val nonRetrofit: Retrofit by lazy {
createRetrofit(commonOkHttpClient)
}

// 토큰이 있는 Retrofit
val retrofit: Retrofit by lazy {
createRetrofit(createTokenOkHttpClient())
}

// 멀티파트 레트로핏
val mRetrofit: Retrofit by lazy {
createRetrofit(createMultiPartOkHttpClient())
}

private fun createRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
Expand All @@ -88,124 +73,139 @@ object RetrofitImpl {
.build()
}

private fun createTokenOkHttpClient(): OkHttpClient {
return commonOkHttpClient.newBuilder()
.addInterceptor(AppInterceptor(App.appContext))
.build()
}

private fun createMultiPartOkHttpClient(): OkHttpClient {
return commonOkHttpClient.newBuilder()
.addInterceptor(mAppInterceptor())
.build()
}

private class AppInterceptor(val context: Context) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response = with(chain) {
var response: Response
val originalRequest = request()
val requestBuilder = originalRequest.newBuilder()
.addHeader("accept", "application/hal+json")
.addHeader("Content-Type", "application/json")
.addHeader(
"Authorization",
"Bearer ${MySharedPreferences.getAccessToken(App.appContext)}"
)

val request = requestBuilder.build()
response = proceed(request)

// Unauthorized (401) 상태 코드를 받았을 경우 토큰 재발급 시도
if (response.code == 401) {
response.close()

Log.d("AppInterceptor", "토큰 재발급 시도")

try {
val refreshTokenRequest = originalRequest.newBuilder()
.post("".toRequestBody())
.url("${BuildConfig.BASE_URL}/oauths/reissue/token")
.addHeader(
"Authorization",
"Bearer ${MySharedPreferences.getRefreshToken(App.appContext)}"
)
.build()

Log.d(TokenInterceptor.TAG, "재발급 중")

val refreshTokenResponse = chain.proceed(refreshTokenRequest)
Log.d(TokenInterceptor.TAG, " : $refreshTokenResponse")

if (refreshTokenResponse.isSuccessful) {
Log.d(TokenInterceptor.TAG, "재발급 성공")

val responseToken = parseRefreshTokenResponse(refreshTokenResponse)

responseToken?.result?.let {
runBlocking {
MySharedPreferences.setAccessToken(
App.appContext,
it.accessToken
)
MySharedPreferences.setRefreshToken(
App.appContext,
it.refreshToken
)

newAccessToken = it.accessToken
}
}

refreshTokenResponse.close()
val newRequest = originalRequest.newAuthBuilder().build()
return chain.proceed(newRequest)
}

} catch (e: Exception) {
runBlocking { MySharedPreferences.clearUser(App.appContext) }
Log.d(TokenInterceptor.TAG, "재발급 실패 $e")

Handler(Looper.getMainLooper()).post {
val context = App.appContext
Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
context.startActivity(intent)
}
}
}
response
}
}

private fun Request.newAuthBuilder() =
this.newBuilder().addHeader("Authorization", "Bearer $newAccessToken")


private class mAppInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response = with(chain) {
val requestBuilder = request().newBuilder()
.addHeader("Content-Type", "multipart/form-data")
.addHeader(
"Authorization",
"Bearer ${MySharedPreferences.getAccessToken(App.appContext)}"
)

val newRequest = requestBuilder.build()
proceed(newRequest)
}
// 토큰 없는 Retrofit
val nonRetrofit: Retrofit by lazy {
createRetrofit(commonOkHttpClient)
}


private fun parseRefreshTokenResponse(response: Response): BaseResponse<TokenResponse>? {
return try {
val gson = Gson()
val responseType: Type = object : TypeToken<BaseResponse<TokenResponse>>() {}.type
gson.fromJson(response.body?.string(), responseType)
} catch (e: Exception) {
null
}
}
// // 토큰이 있는 Retrofit
// val retrofit: Retrofit by lazy {
// createRetrofit(createTokenOkHttpClient())
// }

// // 멀티파트 레트로핏
// val mRetrofit: Retrofit by lazy {
// createRetrofit(createMultiPartOkHttpClient())
// }

// private fun createTokenOkHttpClient(): OkHttpClient {
// return commonOkHttpClient.newBuilder()
// .addInterceptor(AppInterceptor(App.appContext))
// .build()
// }

// private fun createMultiPartOkHttpClient(): OkHttpClient {
// return commonOkHttpClient.newBuilder()
// .addInterceptor(mAppInterceptor())
// .build()
// }

// private class AppInterceptor(val context: Context) : Interceptor {
// @Throws(IOException::class)
// override fun intercept(chain: Interceptor.Chain): Response = with(chain) {
// var response: Response
// val originalRequest = request()
// val requestBuilder = originalRequest.newBuilder()
// .addHeader("accept", "application/hal+json")
// .addHeader("Content-Type", "application/json")
// .addHeader(
// "Authorization",
// "Bearer ${MySharedPreferences.getAccessToken(App.appContext)}"
// )
//
// val request = requestBuilder.build()
// response = proceed(request)
//
// // Unauthorized (401) 상태 코드를 받았을 경우 토큰 재발급 시도
// if (response.code == 401) {
// response.close()
//
// Log.d("AppInterceptor", "토큰 재발급 시도")
//
// try {
// val refreshTokenRequest = originalRequest.newBuilder()
// .post("".toRequestBody())
// .url("${BuildConfig.BASE_URL}/oauths/reissue/token")
// .addHeader(
// "Authorization",
// "Bearer ${MySharedPreferences.getRefreshToken(App.appContext)}"
// )
// .build()
//
// Log.d(TokenInterceptor.TAG, "재발급 중")
//
// val refreshTokenResponse = chain.proceed(refreshTokenRequest)
// Log.d(TokenInterceptor.TAG, " : $refreshTokenResponse")
//
// if (refreshTokenResponse.isSuccessful) {
// Log.d(TokenInterceptor.TAG, "재발급 성공")
//
// val responseToken = parseRefreshTokenResponse(refreshTokenResponse)
//
// responseToken?.result?.let {
// runBlocking {
// MySharedPreferences.setAccessToken(
// App.appContext,
// it.accessToken
// )
// MySharedPreferences.setRefreshToken(
// App.appContext,
// it.refreshToken
// )
//
// newAccessToken = it.accessToken
// }
// }
//
// refreshTokenResponse.close()
// val newRequest = originalRequest.newAuthBuilder().build()
// return chain.proceed(newRequest)
// }
//
// } catch (e: Exception) {
// runBlocking { MySharedPreferences.clearUser(App.appContext) }
// Log.d(TokenInterceptor.TAG, "재발급 실패 $e")
//
// Handler(Looper.getMainLooper()).post {
// val context = App.appContext
// Toast.makeText(context, "토큰이 만료되어 로그아웃 됩니다.", Toast.LENGTH_SHORT).show()
// val intent = Intent(context, LoginActivity::class.java) // 로그인 화면으로 이동
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
// context.startActivity(intent)
// }
// }
// }
// response
// }
// }

// private fun Request.newAuthBuilder() =
// this.newBuilder().addHeader("Authorization", "Bearer $newAccessToken")


// private class mAppInterceptor : Interceptor {
// @Throws(IOException::class)
// override fun intercept(chain: Interceptor.Chain): Response = with(chain) {
// val requestBuilder = request().newBuilder()
// .addHeader("Content-Type", "multipart/form-data")
// .addHeader(
// "Authorization",
// "Bearer ${MySharedPreferences.getAccessToken(App.appContext)}"
// )
//
// val newRequest = requestBuilder.build()
// proceed(newRequest)
// }
// }
//
//
// private fun parseRefreshTokenResponse(response: Response): BaseResponse<TokenResponse>? {
// return try {
// val gson = Gson()
// val responseType: Type = object : TypeToken<BaseResponse<TokenResponse>>() {}.type
// gson.fromJson(response.body?.string(), responseType)
// } catch (e: Exception) {
// null
// }
// }
}
Loading