Skip to content

[Feat/#86] KConnect OAuth 클라이언트 구현 - #91

Merged
tnals0924 merged 7 commits into
mainfrom
feat/#86-kconnect-client
Oct 2, 2026
Merged

tnals0924 merged 7 commits into
mainfrom
feat/#86-kconnect-client

Conversation

@tnals0924

@tnals0924 tnals0924 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

#️⃣연관된 이슈

🎯 해결하려는 문제가 무엇인가요?

OAuthClient의 KConnect(국민대 학생용 OAuth) 구현체를 추가합니다.

❓ 왜 해결해야 하나요?

국민대 학생 로그인 수단이 KConnect입니다. 또 KConnect 측에서 API 명세를 공개하지 말아 달라고 요청해서, 주소·경로·응답 필드를 코드에 두지 않아야 합니다(이 저장소는 public).

⭐ 어떻게 해결했나요?

  • 흐름: 토큰 교환(authorization code + PKCE code verifier + client secret, form) → 사용자 정보 조회(Bearer) → 응답 JSON에서 설정된 필드 이름으로 값 추출
  • 명세는 전부 환경 변수(oauth.kconnect.*): 코드에는 범용 "code 교환 + JSON 매핑"만 남았습니다. .env.example에는 자리표시자만 있고 실제 값은 팀 내부 문서에 있습니다.
  • 타임아웃: 연결 3초, 응답 5초 (KConnectClientConfig의 RestClient 빈)
  • 에러 매핑
    • invalid_grant(code 만료·재사용·verifier 불일치) → 401 INVALID_AUTHORIZATION_CODE
    • invalid_client 등 그 밖의 4xx → IllegalStateException → 500 + error 로그(서버 설정 오류라 알아야 함)
    • 5xx·연결 실패·타임아웃 → 502 OAUTH_PROVIDER_UNAVAILABLE
  • 토큰 교환은 재시도하지 않습니다(code는 1회용).
  • code·verifier·access token·client secret은 로그와 예외 메시지에 남기지 않습니다.
  • 필수 설정이 비어 있으면 기동은 되고 warn 로그에 빠진 키 이름만 남깁니다. 이 상태에서 로그인하면 500입니다.

🧩 이 PR의 한계 & 트레이드오프

  • 응답 필드 이름이 문자열 설정이라 오타를 컴파일러가 잡지 못합니다. 누락만 검사합니다.
  • provider access token은 저장하지 않습니다. KConnect API를 다시 불러야 하는 기능이 생기면 그때 검토합니다.
  • 실제 KConnect와의 end-to-end는 dev 배포 후 확인이 필요합니다. 로컬에서는 목 서버로 매핑·에러 매핑을 확인했습니다.

⛓️ 기존 기능에 미치는 영향

  • infrastructure:client가 core:domain:auth에 의존합니다.
  • 새 환경 변수 KCONNECT_*를 Coolify dev/prod에 등록해야 합니다(.env.example 참고). 등록하지 않아도 기동은 됩니다.

🔀 Edge Case & 실패 시나리오

  • 사용자 정보 응답에 고유 ID가 없거나 응답이 비어 있으면 500
  • 방금 받은 토큰으로 사용자 정보 조회가 4xx면 scope·경로 설정 문제로 보고 500

📋 검토한 대안과 선택 이유

  • KConnect 연동만 별도 private 레포로 분리: 배포 이미지가 public이라 디컴파일하면 보이고, 포트 배포·CI 토큰·권한 없는 팀원 빌드 문제로 복잡도가 커서 설정 주입 방식을 택했습니다.
  • 응답을 record로 역직렬화: 필드 이름이 코드에 남아 제외했습니다.

💬 리뷰 포인트

  • 에러 매핑과 설정 누락 처리 방식
  • 명세(주소·경로·필드 이름)가 코드·주석·설정 기본값에 남지 않았는지

@tnals0924 tnals0924 self-assigned this Sep 30, 2026
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: billilge/stream-server/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 5677bae6-6145-44f0-aa2c-45191b35816a

📥 Commits

Reviewing files that changed from the base of the PR and between 55b41b6 and 4f450f0.

📒 Files selected for processing (24)
  • .env.example
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/domain/Department.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/domain/Member.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/domain/MemberErrorCode.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/domain/MemberProfileCommand.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/domain/TermType.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/repository/MemberRepository.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/repository/MemberTermAgreementRepository.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/service/MemberService.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/service/MemberTermService.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/service/impl/MemberServiceImpl.java
  • core/domain/member/src/main/java/kr/ac/kookmin/stream/member/domain/member/service/impl/MemberTermServiceImpl.java
  • infrastructure/client/build.gradle.kts
  • infrastructure/client/src/main/java/kr/ac/kookmin/stream/client/oauth/kconnect/KConnectClientConfig.java
  • infrastructure/client/src/main/java/kr/ac/kookmin/stream/client/oauth/kconnect/KConnectOAuthClient.java
  • infrastructure/client/src/main/java/kr/ac/kookmin/stream/client/oauth/kconnect/KConnectProperties.java
  • infrastructure/client/src/main/java/kr/ac/kookmin/stream/client/oauth/kconnect/KConnectTokenResponse.java
  • infrastructure/client/src/main/resources/application-infrastructure-client.yml
  • infrastructure/db/src/main/java/kr/ac/kookmin/stream/db/member/MemberJpaEntity.java
  • infrastructure/db/src/main/java/kr/ac/kookmin/stream/db/member/MemberJpaRepository.java
  • infrastructure/db/src/main/java/kr/ac/kookmin/stream/db/member/MemberRepositoryImpl.java
  • infrastructure/db/src/main/java/kr/ac/kookmin/stream/db/member/MemberTermAgreementJpaRepository.java
  • infrastructure/db/src/main/java/kr/ac/kookmin/stream/db/member/MemberTermAgreementRepositoryImpl.java
  • infrastructure/db/src/main/resources/db/migration/V14__add_academic_status_to_members.sql
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

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

form.add("grant_type", "authorization_code");
form.add("code", command.code());
form.add("redirect_uri", command.redirectUri());
form.add("code_verifier", command.codeVerifier());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PKCE가 redirect구간을 지키고 confidential client에서도 넣는 이유는 code injection 방어때문이라고 이해했는데, 이러한 이유로 추가 하신것인지 궁금합니다! 아니면 KConnect가 필수로 요구하는걸까요?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

이해하신 부분도 맞지만 kconnect가 필수로 요구하는 부분도 맞다고 생각하시면 될 거 같습니다!

@jjunh33 jjunh33 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

확인했습니다. client_secret을 이용한 기존 OAuth 로그인 플로우에서, 토큰 발급시 PKCE로 랜덤 문자열을 해시한 값을 키로 사용해 이중으로 검증하는 플로우로 이해했습니다!

@tnals0924
tnals0924 changed the base branch from feat/#84-member-oauth-profile to main October 2, 2026 09:40
@tnals0924
tnals0924 merged commit 93c4ce1 into main Oct 2, 2026
1 check passed
@tnals0924
tnals0924 deleted the feat/#86-kconnect-client branch October 2, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

KConnect OAuth 클라이언트 구현

3 participants