Skip to content

MOSU-341 refactor: 카카오 회원 중복 시 에러 처리#342

Merged
wlgns12370 merged 2 commits intodevelopfrom
refactor/mosu-341
Aug 12, 2025
Merged

MOSU-341 refactor: 카카오 회원 중복 시 에러 처리#342
wlgns12370 merged 2 commits intodevelopfrom
refactor/mosu-341

Conversation

@wlgns12370
Copy link
Contributor

@wlgns12370 wlgns12370 commented Aug 12, 2025

✨ 구현한 기능

📢 논의하고 싶은 내용

  • x

🎸 기타

  • x

Summary by CodeRabbit

  • New Features

    • More informative OAuth login failure responses with standardized error codes (e.g., CANCELED, DUPLICATE).
    • Redirect now includes an OAuth-specific error payload for clearer troubleshooting.
    • Enhanced profile sync during OAuth sign-in, updating phone number, birth date, marketing consent, gender, and name.
  • Bug Fixes

    • Properly detects duplicate OAuth accounts and returns a clear DUPLICATE error instead of a generic failure.

@coderabbitai
Copy link

coderabbitai bot commented Aug 12, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Implements duplicate OAuth user detection with a new OAuthException, expands user update with phone, birth, and marketing flags, and revises OAuth2 login failure handling to emit OAuth-specific error responses using OAuthErrorType and OAuthFailureResponse. Removes an unused LoginResponse factory.

Changes

Cohort / File(s) Summary
OAuth persistence
src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserPersistenceProcessor.java
Adds duplicate-user check throwing OAuthException("DUPLICATE"); updates existing-user update call to include gender, name, formatted phone, birth day, and marketing consent; imports OAuthException.
Exception type
src/main/java/life/mosu/mosuserver/global/exception/OAuthException.java
Introduces OAuthException extending AuthenticationException with message constructor.
Failure handling and DTOs
src/main/java/life/mosu/mosuserver/global/handler/OAuth2LoginFailureHandler.java, src/main/java/life/mosu/mosuserver/global/handler/OAuthErrorType.java, src/main/java/life/mosu/mosuserver/global/handler/OAuthFailureResponse.java, src/main/java/life/mosu/mosuserver/presentation/auth/dto/request/LoginResponse.java
Replaces LoginResponse-based failure payload with OAuthFailureResponse derived from OAuthErrorType; adds OAuthErrorType enum and OAuthFailureResponse record; removes LoginResponse.from() no-arg factory.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App
  participant OAuthProvider as OAuth Provider
  participant Server as Mosu Server

  User->>App: Start OAuth login
  App->>OAuthProvider: Redirect to authorize
  OAuthProvider-->>App: Redirect back (error or code)
  App->>Server: /oauth2/callback (error or code)

  alt Error present
    Server->>Server: OAuth2LoginFailureHandler.onAuthenticationFailure()
    Server->>Server: Map message -> OAuthErrorType
    Server->>App: Redirect with data=OAuthFailureResponse(JSON)
  else Code present
    Server->>Server: Persist/Update OAuth user
    alt Existing Mosu user detected as duplicate
      Server->>Server: throw OAuthException("DUPLICATE")
      Server->>App: Redirect with data=OAuthFailureResponse("DUPLICATE")
    else New or updatable user
      Server-->>App: Proceed with normal success flow
    end
  end
Loading
sequenceDiagram
  participant Processor as OAuthUserPersistenceProcessor
  participant Repo as User Repository
  participant Entity as UserJpaEntity

  Processor->>Repo: findByProviderId(...)
  alt Existing user
    Processor->>Entity: updateOAuthUser(gender, name, phone, birth, marketing)
  else No user
    Processor->>Repo: save(new OAuth user)
  end

  alt existingUser.isMosuUser()
    Processor->>Processor: throw OAuthException("DUPLICATE")
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested labels

우선순위 중

Poem

A hop, a skip, I nibble code anew—
Duplicate tracks? I mark them “DUPLICATE,” shoo!
If auth winds fail, I wave a tidy sign,
CANCELED or UNKNOWN, errors now align.
With phone and birth and carrot-bright consent,
I bound through fields—persistent and content. 🥕✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcaecf1 and 80537c4.

📒 Files selected for processing (6)
  • src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserPersistenceProcessor.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/global/exception/OAuthException.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/global/handler/OAuth2LoginFailureHandler.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/global/handler/OAuthErrorType.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/global/handler/OAuthFailureResponse.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/auth/dto/request/LoginResponse.java (0 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/mosu-341

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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.

Summary of Changes

Hello @wlgns12370, 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은 OAuth 인증 과정에서 발생하는 오류 처리를 리팩토링하여, 특히 카카오 회원 중복 가입 시 발생하는 오류를 명확하게 처리하고 OAuth 관련 오류 응답을 표준화합니다. 이를 통해 사용자에게 더 구체적인 오류 정보를 제공하고, 오류 처리 로직의 일관성을 높입니다.

Highlights

  • 카카오 회원 중복 에러 처리: 기존에 주석 처리되어 있던 카카오 회원 중복 가입 로직을 활성화하고, IllegalArgumentException 대신 새로 정의된 OAuthException을 사용하여 'DUPLICATE' 오류를 발생시키도록 변경했습니다.
  • OAuth 전용 예외 도입: OAuth 인증 과정에서 발생하는 특정 오류를 처리하기 위해 AuthenticationException을 상속받는 OAuthException 클래스를 새로 추가했습니다.
  • OAuth 오류 타입 및 응답 표준화: OAuth 오류를 'CANCELED', 'DUPLICATE', 'UNKNOWN' 등으로 분류하는 OAuthErrorType 열거형과, 표준화된 오류 응답 형식을 제공하는 OAuthFailureResponse 레코드를 도입하여 오류 처리의 일관성을 확보했습니다.
  • OAuth 로그인 실패 핸들러 개선: OAuth2LoginFailureHandler에서 기존의 일반적인 LoginResponse 대신 새로 정의된 OAuthErrorType과 OAuthFailureResponse를 사용하여 로그인 실패 시 더 구체적인 오류 정보를 클라이언트에 전달하도록 로직을 수정했습니다.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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 issue 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.

@wlgns12370 wlgns12370 merged commit f888537 into develop Aug 12, 2025
2 of 3 checks passed
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

안녕하세요. 카카오 회원 중복 및 OAuth 관련 에러 처리 리팩토링 PR 잘 보았습니다.

전반적으로 OAuth 인증 실패 시 에러를 공통으로 처리하기 위한 구조를 잘 설계하셨습니다. OAuthException, OAuthErrorType, OAuthFailureResponse를 도입하여 에러 처리 로직을 명확하게 분리한 점이 인상적입니다.

다만, 코드의 안정성과 유지보수성을 높이기 위해 몇 가지 개선점을 제안합니다.
주요 제안 내용은 다음과 같습니다:

  • OAuth2LoginFailureHandler에서 OAuth2AuthenticationException의 에러 코드를 직접 사용하여, 외부 OAuth 제공자의 에러 메시지 변경에 대한 의존성을 제거하는 것을 제안합니다.
  • 하드코딩된 에러 메시지 문자열을 OAuthErrorType enum으로 대체하여 타입 안정성을 확보하고 코드 일관성을 높이는 방안을 제안합니다.

자세한 내용은 각 파일에 남긴 리뷰 코멘트를 참고해주세요.

Comment on lines +29 to +31
OAuthErrorType errorType = OAuthErrorType.from(exception.getMessage());
OAuthFailureResponse oAuthFailureResponse = OAuthFailureResponse.from(
errorType.getMessage());

Choose a reason for hiding this comment

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

high

exception.getMessage()를 직접 사용하여 에러 유형을 확인하는 것은 OAuth 제공자의 에러 메시지 변경에 취약할 수 있습니다.

AuthenticationExceptionOAuth2AuthenticationException의 인스턴스인 경우, getError().getErrorCode()를 통해 보다 안정적으로 에러 코드를 추출할 수 있습니다. 이렇게 하면 "access_denied"와 같은 표준 에러 코드를 사용하여 OAuthErrorType에서 분기 처리를 할 수 있어 코드가 더 견고해집니다.

이 변경을 적용하려면 org.springframework.security.oauth2.core.OAuth2AuthenticationException를 import해야 합니다.

OAuthErrorType.java의 관련 수정 제안도 함께 확인해주세요.

        String errorCode = exception.getMessage();
        if (exception instanceof org.springframework.security.oauth2.core.OAuth2AuthenticationException e) {
            errorCode = e.getError().getErrorCode();
        }

        OAuthErrorType errorType = OAuthErrorType.from(errorCode);
        OAuthFailureResponse oAuthFailureResponse = OAuthFailureResponse.from(
                errorType.getMessage());

Comment on lines +21 to +25
return switch (text) {
case "DUPLICATE" -> DUPLICATE;
case "[access_denied] User denied access" -> CANCELED;
default -> UNKNOWN;
};

Choose a reason for hiding this comment

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

high

에러 메시지 문자열 "[access_denied] User denied access"에 직접 의존하는 것은 좋지 않은 방법입니다. OAuth 제공자가 에러 메시지 형식을 변경하면 코드가 오작동할 수 있습니다.

OAuth2LoginFailureHandler에서 exception 객체가 OAuth2AuthenticationException의 인스턴스인지 확인하고, 그렇다면 getError().getErrorCode()를 사용하여 "access_denied"와 같은 표준 오류 코드를 가져오는 것이 더 안정적입니다.

관련하여 OAuth2LoginFailureHandler.java 파일에도 수정 제안을 남겼습니다. 이 제안과 함께 적용하는 것을 권장합니다.

아래와 같이 수정할 수 있습니다.

Suggested change
return switch (text) {
case "DUPLICATE" -> DUPLICATE;
case "[access_denied] User denied access" -> CANCELED;
default -> UNKNOWN;
};
return switch (text) {
case "DUPLICATE" -> DUPLICATE;
case "access_denied" -> CANCELED;
default -> UNKNOWN;
};

// throw new IllegalArgumentException("이미 모수 회원입니다.");
// }
if (existingUser.isMosuUser()) {
throw new OAuthException("DUPLICATE");

Choose a reason for hiding this comment

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

medium

에러 메시지로 하드코딩된 문자열 "DUPLICATE"을 사용하는 대신, OAuthErrorType enum을 직접 사용하여 타입 안정성을 높이고 유지보수를 용이하게 하는 것이 좋습니다. OAuthErrorType.DUPLICATE.getMessage()를 사용하면, 향후 에러 코드 문자열이 변경되더라도 한 곳(OAuthErrorType enum)에서만 수정하면 되므로 코드 관리가 더 수월해집니다. 이 변경을 적용하려면 life.mosu.mosuserver.global.handler.OAuthErrorType를 import해야 합니다.

Suggested change
throw new OAuthException("DUPLICATE");
throw new OAuthException(OAuthErrorType.DUPLICATE.getMessage());

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.

[🛠 리팩토링] 카카오 회원 중복 시 에러 처리

1 participant