Skip to content
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

[CAT-69] 디바이스 및 유저 인증 모듈 구현 #29

Merged
merged 17 commits into from
Jul 24, 2024
Merged

Conversation

HyomK
Copy link
Member

@HyomK HyomK commented Jul 23, 2024

작업 내용

  • file name lint 추가
  • 디바이스 아이디 발급 로직 구현
  • DeviceId, Token LocalDataSource 구현
  • NetworkModule Qualifier 추가
  • HttpLogger 추가
  • TokenRefreshInterceptor 구현
  • Auth RemoteDataSource구현

이후 AuthRepository에서 datasource 사용하여 유저 정보 로직 처리

체크리스트

  • 빌드 확인
  • TokenRefreshInterceptor 때문에 PomonyangService 하나로 쓰니까 di cycle 생겨서 AuthService만 분리할까 하는데 괜찮은지 의견주세요!

AuthService를 사용한다면, 토큰 갱신 외 유저 등록, 탈퇴 api 가 들어갈 것 같네요

동작 화면

SSAID 발급 로그
image

TokenRefresh 테스트
App Inspector를 이용하여 테스트함
특정 API호출 - (401 : 토큰만료) -> AccessToken Refresh API 호출 -> 특정 API 재호출

2024-07-23.11.52.32.mov

살려주세요

@HyomK HyomK added the feature 기능 개발 label Jul 23, 2024
@HyomK HyomK self-assigned this Jul 23, 2024
@github-actions github-actions bot requested a review from lee-ji-hoon July 23, 2024 15:04
Copy link

linear bot commented Jul 23, 2024

Comment on lines 22 to 25
companion object {
const val DEVICE_ID_PREFERENCES_NAME = "device_id_preferences"
private val DEVICE_ID_KEY = stringPreferencesKey("device_id")
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

image

companion object 최하단에 부탁할게~!

https://kotlinlang.org/docs/coding-conventions.html#class-layout

Comment on lines 29 to 40
private suspend fun getStoredDeviceId(): String? = try {
dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.first()[DEVICE_ID_KEY]
} catch (exception: IOException) {
null
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기 코드에 의도가 궁금해

dataStore 전체를 catch하는데 이때 IO면 null인데 내부에서 IO가 터지면 emptyPreferences 를 반환하는데 IO가 아니면 throw를 하고 있어서 어떤 의도인지 간략하게 알 수 있을까?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

하나 찾았다. try - catch

Comment on lines 15 to 20
@Binds
abstract fun provideTokenDataSource(tokenDataSourceImpl: TokenDataSourceImpl): TokenDataSource

@Binds
abstract fun provideDeviceIdDataSource(deviceIdDataSourceImpl: DeviceIdDataSourceImpl): DeviceIdDataSource
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이번에 추가한것들 중에 DataSource나 몇몇 클래스들 Singleton으로 안한 이유가 혹시 있을까?

Copy link
Member Author

Choose a reason for hiding this comment

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

요거는 제가 놓친 부분인것 같네요 Singleton annotation 추가하기로

Comment on lines 27 to 28
@Module
@InstallIn(SingletonComponent::class)
Copy link
Collaborator

Choose a reason for hiding this comment

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

NetworkModule 클래스에서 전체적으로 정렬이 뭔가 달라진거 같은데 나랑 혹시 옵션이 뭔가 다른건지 아니면 ktlint로 인해서 자동 정렬이 된건지 알 수 있을까?

//
fun provideTokenInterceptorRetrofit(
    @TokenClient okHttpClient: OkHttpClient,
    networkResultCallAdapterFactory: NetworkResultCallAdapterFactory,
    json: Json
): Retrofit = Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(BASE_URL)
    .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
    .addCallAdapterFactory(networkResultCallAdapterFactory)
    .build()

//
fun provideTokenInterceptorRetrofit(
    @TokenClient okHttpClient: OkHttpClient,
    networkResultCallAdapterFactory: NetworkResultCallAdapterFactory,
    json: Json
): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL).addConverterFactory(json.asConverterFactory("application/json".toMediaType())).addCallAdapterFactory(networkResultCallAdapterFactory).build()

Copy link
Member Author

Choose a reason for hiding this comment

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

 @Provides
        @Singleton
        @TokenApi
        fun provideTokenInterceptorRetrofit(
            @TokenClient okHttpClient: OkHttpClient,
            networkResultCallAdapterFactory: NetworkResultCallAdapterFactory,
            json: Json
        ): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL).addConverterFactory(json.asConverterFactory("application/json".toMediaType())).addCallAdapterFactory(networkResultCallAdapterFactory).build()

Copy link
Member Author

Choose a reason for hiding this comment

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

오잉 저도 안스 기준 이렇게 되어있는데 lint로 자동 정렬되어서 올라가나

Copy link
Member Author

Choose a reason for hiding this comment

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

일단은 response,request는 임시로 만들어놨어!

override fun intercept(chain: Interceptor.Chain): Response {
val origin = chain.request()
val response = chain.proceed(origin)
if (response.code == 401) {
Copy link
Member Author

Choose a reason for hiding this comment

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

대부분 401롤 처리해줘서 Authenticator 로도 할 수 있지만, 혹시를 대비해서 Interceptor로 만들어봤어요

.newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Accept", "*/*")
.addHeader("Authorization", "Bearer $accessToken")
Copy link
Member Author

Choose a reason for hiding this comment

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

여기도 나중에 서버 요청에 따라 바꾸는 걸로

Comment on lines 29 to 40
private suspend fun getStoredDeviceId(): String? = try {
dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}.first()[DEVICE_ID_KEY]
} catch (exception: IOException) {
null
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines 15 to 20
@Binds
abstract fun provideTokenDataSource(tokenDataSourceImpl: TokenDataSourceImpl): TokenDataSource

@Binds
abstract fun provideDeviceIdDataSource(deviceIdDataSourceImpl: DeviceIdDataSourceImpl): DeviceIdDataSource
}
Copy link
Member Author

Choose a reason for hiding this comment

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

요거는 제가 놓친 부분인것 같네요 Singleton annotation 추가하기로

Comment on lines 27 to 28
@Module
@InstallIn(SingletonComponent::class)
Copy link
Member Author

Choose a reason for hiding this comment

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

 @Provides
        @Singleton
        @TokenApi
        fun provideTokenInterceptorRetrofit(
            @TokenClient okHttpClient: OkHttpClient,
            networkResultCallAdapterFactory: NetworkResultCallAdapterFactory,
            json: Json
        ): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL).addConverterFactory(json.asConverterFactory("application/json".toMediaType())).addCallAdapterFactory(networkResultCallAdapterFactory).build()

Comment on lines 27 to 28
@Module
@InstallIn(SingletonComponent::class)
Copy link
Member Author

Choose a reason for hiding this comment

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

오잉 저도 안스 기준 이렇게 되어있는데 lint로 자동 정렬되어서 올라가나

Copy link
Collaborator

@lee-ji-hoon lee-ji-hoon left a comment

Choose a reason for hiding this comment

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

토큰과 관련이 되면서 이것저것 복잡하던 부분 잘 구현된거 같아 고생했어~!

@HyomK HyomK merged commit c8fe90a into develop Jul 24, 2024
@HyomK HyomK deleted the feature/cat-69 branch July 24, 2024 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 기능 개발
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants