Skip to content

Conversation

@stopstone
Copy link
Contributor

작업 내용

1. 카카오 로그인 시 카카오톡 앱 이동 기능 구현

  • ApplicationContext 대신 ActivityContext를 사용하도록 변경
  • ActivityContextProvider 패턴을 도입하여 Data Layer에서 Activity Context 사용
  • MainActivity에서 ActivityContextProviderImpl에 Context 설정 및 해제

2. 로그인 플로우 개선

  • 카카오 로그인 성공 시 즉시 서버 전송하지 않고 AccessToken만 임시 저장
  • 개인정보 동의 완료 후 서버에 토큰 전송 및 DataStore에 저장
  • 카카오톡 앱에서 취소 시 웹뷰로 fallback하지 않고 로그인 취소 처리

확인 방법

  1. 카카오톡 설치 상태에서 로그인 버튼 클릭
  2. 카카오톡 앱으로 이동하여 로그인
  3. 로그인 성공 후 Near 앱으로 자동 복귀
  4. 개인정보 동의 바텀시트에서 약관 동의 후 가입 버튼 클릭
  5. 홈 화면으로 이동 확인

카카오톡 미설치 상태:

  1. 로그인 버튼 클릭
  2. 웹뷰로 로그인
  3. 성공 후 Near 앱으로 복귀

참고 사항

ActivityContext 주입 방식 선택

문제 발생 과정

  • 초기에는 @ActivityContext 어노테이션을 직접 사용하려 했으나, Hilt의 Component 계층 구조상 불가능했습니다.
  • @ActivityContext는 ActivityComponent에서만 제공되는데, ActivityComponent의 클래스를 ViewModel에 주입할 수 없는 문제가 발생했습니다.
  • ViewModel은 ViewModelComponent를 사용하며, ViewModelComponent는 ActivityRetainedComponent의 하위 컴포넌트입니다.
  • ActivityComponent와 ActivityRetainedComponent는 서로 다른 생명주기와 스코프를 가지고 있어, ActivityScoped 클래스를 ActivityRetainedScoped나 Singleton 클래스에서 주입받을 수 없었습니다.

해결 방안 검토

  1. Context를 파라미터로 전달: 간단하지만 안드로이드 의존성의 간섭이 많아집니다.
  2. ActivityContextProvider 패턴 도입: 최종 선택

최종 해결 방법

  • ActivityContextProvider 인터페이스를 Data Layer에 정의
  • ActivityContextProviderImpl 구현체를 Presentation Layer에 배치하였습니다.
  • MainActivity에서 onCreate/onDestroy 시점에 ActivityContextProviderImpl에 Context를 설정/해제

관련 이슈

- 카카오 로그인과 같이 Activity Context가 필요한 기능을 위해 `ActivityContextProvider`를 도입했습니다.
- Hilt를 사용하여 `ActivityContextProvider`의 구현체인 `ActivityContextProviderImpl`을 싱글톤으로 주입하도록 설정했습니다.
- `MainActivity`의 생명주기에 맞춰 `onCreate`에서 Context를 설정하고 `onDestroy`에서 해제하도록 변경했습니다.
- `KakaoDataSource`에서 카카오 로그인 시 `Application Context` 대신 `ActivityContextProvider`를 통해 `Activity Context`를 우선적으로 사용하도록 수정했습니다.
- 기존에 소셜 로그인 성공 즉시 서버로 토큰을 전송하던 로직을 변경했습니다.
- 이제 소셜 로그인 플랫폼에서 액세스 토큰을 먼저 받아온 후, 사용자가 개인정보처리방침에 동의하는 시점에 해당 토큰을 서버로 전송하여 최종 로그인을 완료하도록 수정했습니다.
@stopstone stopstone linked an issue Oct 19, 2025 that may be closed by this pull request
@gemini-code-assist
Copy link

Summary of Changes

Hello @stopstone, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 카카오 소셜 로그인 프로세스를 개선하여 사용자 경험을 향상시키고 아키텍처를 강화합니다. 카카오톡 앱을 통한 직접 로그인 기능을 구현하고, 로그인 성공 후 개인정보 동의 절차를 거쳐야만 토큰이 서버로 전송되도록 로그인 플로우를 재정비했습니다. 특히, Hilt 환경에서 ActivityContext를 안전하게 관리하기 위한 ActivityContextProvider 패턴을 도입하여 메모리 누수 위험을 줄이고 의존성 주입 문제를 해결했습니다.

Highlights

  • 카카오톡 앱 이동 기능 구현: 카카오 로그인 시 ApplicationContext 대신 ActivityContext를 사용하도록 변경하여, 카카오톡 앱으로 직접 이동하는 기능을 구현했습니다. 이를 위해 ActivityContextProvider 패턴을 도입하여 Data Layer에서 Activity Context를 안전하게 사용할 수 있도록 했습니다.
  • 로그인 플로우 개선: 카카오 로그인 성공 시 AccessToken을 즉시 서버로 전송하지 않고 임시 저장합니다. 이후 개인정보 동의가 완료되면 서버에 토큰을 전송하고 DataStore에 저장하도록 플로우를 개선했습니다. 또한, 카카오톡 앱에서 로그인 취소 시 웹뷰로 fallback하지 않고 로그인 취소로 처리합니다.
  • ActivityContext 주입 방식 해결: Hilt의 Component 계층 구조상 ViewModel에서 ActivityComponent의 @ActivityContext를 직접 주입받을 수 없는 문제를 해결하기 위해 ActivityContextProvider 패턴을 도입했습니다. Data Layer에 인터페이스를 정의하고 Presentation Layer에 구현체를 두어 MainActivity에서 Context를 설정/해제하는 방식으로 Activity Context를 제공합니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

카카오 소셜 로그인 로직 개선을 위한 PR 잘 보았습니다. ActivityContextProvider 패턴을 도입하여 Data Layer에서 Activity Context를 안전하게 사용하는 방식이 인상적입니다. Hilt의 의존성 주입 제약을 창의적으로 해결하신 점이 돋보입니다. 또한, 로그인 플로우를 개선하여 사용자 경험을 향상시킨 점도 좋습니다. 전체적으로 코드 변경 사항이 명확하고, PR 설명도 상세하여 이해하기 쉬웠습니다. 한 가지 잠재적인 문제를 발견하여 리뷰 코멘트를 남겼으니 확인 부탁드립니다.

Comment on lines 87 to 92
val accessToken = tempAccessToken
val providerType = tempProviderType

updateLoadingState(isLoading = true)
authRepository
.socialLogin(accessToken!!, providerType!!)

Choose a reason for hiding this comment

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

high

tempAccessTokentempProviderType!! 연산자를 사용하는 것은 잠재적인 NullPointerException 위험이 있습니다. 예를 들어, 안드로이드 시스템이 메모리 확보를 위해 앱 프로세스를 종료했다가 사용자가 다시 앱으로 돌아오면 ViewModel이 재생성되면서 이 변수들이 null이 될 수 있습니다. 이 경우 !! 연산자로 인해 앱이 비정상 종료됩니다.

이러한 상황을 방지하기 위해, socialLogin을 호출하기 전에 accessTokenproviderTypenull이 아닌지 확인하는 방어 코드를 추가하는 것이 좋습니다. null일 경우, 사용자에게 오류 메시지를 보여주고 다시 로그인을 시도하도록 안내하는 것이 안전합니다.

                val accessToken = tempAccessToken
                val providerType = tempProviderType

                if (accessToken == null || providerType == null) {
                    _loginState.value = _loginState.value.copy(showPrivacyBottomSheet = false)
                    _event.send(LoginEvent.ShowError(Exception("로그인 정보가 유실되었습니다. 다시 시도해주세요.")))
                    return@launch
                }

                updateLoadingState(isLoading = true)
                authRepository
                    .socialLogin(accessToken, providerType)

- 소셜 로그인 과정에서 프로세스 종료로 인해 `accessToken` 또는 `providerType` 정보가 유실되었을 경우, 에러 메시지를 표시하고 로그인 흐름이 중단되도록 예외 처리 로직을 추가했습니다.
- 로그인 성공 시 임시로 저장했던 토큰 정보를 초기화하는 코드를 추가했습니다.
@stopstone stopstone closed this Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 카카오 소셜 로그인 SDK 로직 개선

2 participants