-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
개선된 로그인 반영 (Oauth) #396
개선된 로그인 반영 (Oauth) #396
Changes from all commits
28a8d64
c265c97
9a8e7af
6a05bd9
31061be
c327913
0722eb6
e6cfa71
ef06f5a
65f3e14
9b28fc0
8b9bd0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,15 +9,19 @@ import com.ohdodok.catchytape.core.data.model.ErrorResponse | |
import com.ohdodok.catchytape.core.domain.model.CtErrorType | ||
import com.ohdodok.catchytape.core.domain.model.CtErrorType.Companion.ctErrorEnums | ||
import com.ohdodok.catchytape.core.domain.model.CtException | ||
import com.ohdodok.catchytape.core.domain.repository.AuthRepository | ||
import dagger.Lazy | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.runBlocking | ||
import kotlinx.serialization.json.Json | ||
import okhttp3.Interceptor | ||
import okhttp3.MediaType.Companion.toMediaType | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.logging.HttpLoggingInterceptor | ||
import retrofit2.Retrofit | ||
import timber.log.Timber | ||
|
@@ -33,10 +37,10 @@ object NetworkModule { | |
@AuthInterceptor | ||
@Singleton | ||
@Provides | ||
fun provideAuthInterceptor(tokenDataSource: TokenLocalDataSource): Interceptor { | ||
fun provideAuthInterceptor(tokenLocalDataSource: TokenLocalDataSource): Interceptor { | ||
|
||
return Interceptor { chain -> | ||
val accessToken = runBlocking { tokenDataSource.getAccessToken() } | ||
val accessToken = runBlocking { tokenLocalDataSource.getAccessToken() } | ||
val newRequest = chain.request().newBuilder() | ||
.addHeader("Authorization", "Bearer $accessToken") | ||
.build() | ||
|
@@ -63,7 +67,7 @@ object NetworkModule { | |
fun provideOkHttpClient( | ||
loggingInterceptor: HttpLoggingInterceptor, | ||
@AuthInterceptor authInterceptor: Interceptor, | ||
@ErrorInterceptor errorInterceptor : Interceptor | ||
@ErrorInterceptor errorInterceptor: Interceptor | ||
): OkHttpClient { | ||
return OkHttpClient.Builder() | ||
.addInterceptor(authInterceptor) | ||
|
@@ -87,16 +91,24 @@ object NetworkModule { | |
@ErrorInterceptor | ||
@Singleton | ||
@Provides | ||
fun provideErrorInterceptor(): Interceptor { | ||
fun provideErrorInterceptor( | ||
authRepository: Lazy<AuthRepository> | ||
): Interceptor { | ||
return Interceptor { chain -> | ||
try { | ||
val response = chain.proceed(chain.request()) | ||
val originalRequest = chain.request() | ||
val response = chain.proceed(originalRequest) | ||
if (response.isSuccessful) return@Interceptor response | ||
val errorString = response.body?.string() | ||
val errorResponse = Json.decodeFromString<ErrorResponse>(errorString ?: "") | ||
|
||
if (errorResponse.statusCode == 401) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코드를 자세히 보진 않았는데, 원래 로그인 시도할 때 LoginViewModel에서 401을 받으면 회원가입(닉네임) 화면으로 이동했던 걸로 기억하는데, 이렇게 변경했을 때도 로그인했을 때 미가입 회원일 경우 회원가입 화면으로 잘 이동하는지 확인해 주세용 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://www.notion.so/2024-01-29-refresh-9dbaae6a05f3448ca0294ecbafeba23c 참고하여 개발하였습니다. 참고하여 테스트 해보겠습니다~ |
||
throw CtException(errorResponse.message, CtErrorType.UN_AUTHORIZED) | ||
val newAccessToken = runBlocking { | ||
val authTokenResponse = authRepository.get().refreshToken() | ||
authTokenResponse.first().accessToken | ||
} | ||
val newRequest = originalRequest.putTokenHeader(newAccessToken) | ||
chain.proceed(newRequest) | ||
} | ||
Comment on lines
105
to
112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분 로직은 retrofit의 authenticator를 이용해서 구현할 수도 있어. |
||
|
||
val ctError = ctErrorEnums.find { it.errorCode == errorResponse.errorCode } | ||
|
@@ -108,11 +120,21 @@ object NetworkModule { | |
} catch (e: Exception) { | ||
when (e) { | ||
is ConnectException -> throw CtException(e.message, CtErrorType.CONNECTION) | ||
is SSLHandshakeException -> throw CtException(e.message, CtErrorType.SSL_HAND_SHAKE) | ||
is SSLHandshakeException -> throw CtException( | ||
e.message, | ||
CtErrorType.SSL_HAND_SHAKE | ||
) | ||
|
||
is CtException -> throw e | ||
else -> throw CtException(e.message, CtErrorType.IO) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun Request.putTokenHeader(accessToken: String): Request { | ||
return this.newBuilder() | ||
.addHeader("Authorization", accessToken) | ||
.build() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.ohdodok.catchytape.core.data.model | ||
|
||
import com.ohdodok.catchytape.core.domain.model.AuthToken | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class AuthTokenResponse( | ||
val accessToken: String, | ||
val refreshToken: String, | ||
) { | ||
internal fun toDomain(): AuthToken { | ||
return AuthToken( | ||
accessToken = accessToken, | ||
refreshToken = refreshToken | ||
) | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.ohdodok.catchytape.core.domain.model | ||
|
||
data class AuthToken( | ||
val accessToken: String, | ||
val refreshToken: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,19 @@ | ||
package com.ohdodok.catchytape.core.domain.repository | ||
|
||
import com.ohdodok.catchytape.core.domain.model.AuthToken | ||
import kotlinx.coroutines.flow.Flow | ||
|
||
interface AuthRepository { | ||
|
||
fun loginWithGoogle(googleToken: String): Flow<String> | ||
fun loginWithGoogle(googleToken: String): Flow<AuthToken> | ||
|
||
fun signUpWithGoogle(googleToken: String, nickname: String): Flow<String> | ||
fun signUpWithGoogle(googleToken: String, nickname: String): Flow<AuthToken> | ||
|
||
fun isDuplicatedNickname(nickname: String): Flow<Boolean> | ||
|
||
suspend fun verifyToken(token: String): Boolean | ||
suspend fun verifyAccessToken(): Boolean | ||
|
||
fun refreshToken(): Flow<AuthToken> | ||
|
||
suspend fun saveAuthToken(authToken: AuthToken) | ||
} |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lazy 인 이유는 말씀하신, 3번 처럼 cycle이 일어나는 것 때문에 사용하였습니다.
더 개선할 수 있을거 같은데, 이슈로 따로 빼서 해보겠습니다~�
<참고>