Skip to content

feat: 깃허브 oauth 연동#15

Merged
i3months merged 29 commits into
devfrom
feature/github-oauth
May 15, 2026
Merged

feat: 깃허브 oauth 연동#15
i3months merged 29 commits into
devfrom
feature/github-oauth

Conversation

@pswaao88

Copy link
Copy Markdown
Contributor

변경 사항

PR 요약

GitHub OAuth 기반 로그인 흐름을 구현하고, Core Server 인증 토큰 체계를
추가했습니다.
프론트는 GitHub 로그인 URL 발급 API를 호출하고, callback으로 받은
code/state를 백엔드에 전달하면 Core Server가 GitHub token 교환, 사용자
생성/갱신, 자체 access/refresh token 발급까지 처리합니다.

주요 변경 사항

  • GitHub OAuth 로그인 시작/콜백 API 추가
    • POST /api/auth/github
    • GET /api/auth/github/callback
  • OAuth 보안 처리 추가
    • CSRF 방지용 state 발급/검증
    • PKCE code_verifier, code_challenge 적용
    • OAuth state는 DB에 저장 후 callback에서 1회 사용
  • GitHub API 연동 추가
    • GitHub access token 교환
    • GitHub 사용자 프로필 조회
    • primary verified email 조회
    • GitHub access token AES-GCM 암호화 저장
  • 사용자 생성/갱신 로직 추가
    • github_id 기준 기존 유저 조회
    • 신규 유저 생성
    • 기존 유저 프로필/토큰 갱신
    • soft delete를 고려한 GitHub ID partial unique 제약 적용
  • Core Server 토큰 체계 추가
    • access token: JWT
    • refresh token: 랜덤 opaque token
    • refresh token은 HttpOnly Secure SameSite 쿠키로 전달
    • DB에는 refresh token 원문 대신 SHA-256 hash 저장
    • refresh token rotation/revoke 처리
  • 사용자 프로필 조회 API 추가
    • GET /api/users/me
    • Bearer access token 기반 인증
  • 인증/인가 에러 응답 개선
    • AUTH_INVALID_TOKEN
    • AUTH_EXPIRED_TOKEN
    • AUTH_REVOKED_TOKEN
    • AUTH_GITHUB_OAUTH_FAILED
    • ACCESS_DENIED
  • 설정/환경변수 정리
    • GitHub OAuth client 정보
    • JWT TTL
    • refresh token 정책
    • OAuth state/PKCE 정책
    • GitHub API endpoint/version
    • refresh token cookie 설정
  • Docker/실행 가이드 정리
    • backend Dockerfile
    • .env.example
    • Core Server README

후속 개선 사항

  • 인증/OAuth 실패 로그가 아직 부족해 운영 중 원인 추적을 위해 보강이
    필요합니다. 특히 state 검증, GitHub token exchange, GitHub profile/
    email 조회, token 암호화, user upsert 단계별 실패 지점을 구분해 남기는
    방향으로 개선할 예정입니다. 단, code/access token/refresh token 등 민
    감값은 로그에 남기지 않습니다.

  • DI 코드를 간소화하기 위해 일부 Service/Controller를 record로 전환했
    지만, @Configuration처럼 record 전환 시 Spring 제약이 생기는 경우가
    있었습니다. record와 class가 섞이면 코드 스타일이 애매해질 수 있어, 이
    후에는 일관성을 위해 Spring Bean을 일반 class 기반으로 유지할지도 검토
    가 필요합니다.

@vercel

vercel Bot commented May 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stackup Ready Ready Preview, Comment May 15, 2026 3:01pm

private final Clock clock;

@Autowired
public RefreshTokenService(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

생성자 하나로 합치고 @Autowired 빼는것도 깔끔할듯합니다
SecureRandom과 Clock은 빈으로 등록하고

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

테스트용 생성자 제거했습니다.
OAuthService, RefreshTokenService 생성자 하나로 합치고 빈등록해서 해결했습니다.

우선 패키지 만들지 않고 common.config에 배치했고 설정 늘어나면 패키지 분리해서 관리하겠습니다.

@Component
public class GithubApiClient {

private final RestClient restClient;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

외부 api 호출 시 HTTP Interface를 사용하면 깔끔합니다.
인터페이스만 선언하고 구현체는 프록시가 자동 생성하는 패턴이 있습니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

외부 GIthub API 호출 부분 인터페이스 기준으로 변경했습니다.
실제 요청 경로 코드에 명확하게 보이도록 Github_OAUTH_BaseUrl 과 각 api path로 분리해 처리했습니다.

private final RestClient restClient;

public GithubApiClient(GithubOAuthProperties githubOAuthProperties) {
this.restClient = RestClient.builder()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

타임아웃 관련 설정이 있을까요?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

• 거기까지는 생각하지 못했습니다. 각 상황에 맞게 아래처럼 timeout을 설정 해보겠습니다.

  • connect-timeout 3s: 연결 자체가 3초 이상 걸리면 네트워크 문제로 보고 빠르게 실패 처리
  • read-timeout 5s: OAuth/프로필 조회는 응답이 작아 5초 이상 지연되면 재시도하도록 실패 처리
  • 레포 분석용 GitHub API는 파일 조회가 많아질 수 있어 이후 별도 timeout으로 분리

Comment thread backend/README.md Outdated
배포 프론트 테스트:

```env
GITHUB_OAUTH_REDIRECT_URI=https://www.udangtang.site/auth/callback

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

주소는 수정해야할듯합니다

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

주소 빠르게 테스트하기 위해 했던 흔적이어서 지우겠습니다.

Comment thread backend/README.md Outdated
인프라:

```env
POSTGRES_HOST=localhost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

포트 반영 안되어있네요
로컬이면 상관없긴합니다

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

빠르게 테스트하려고 했던 흔적이어서 배포환경에 맞게 넣을 수 있도록 README.md, application.yml, .env.example 전부 수정했습니다.

@i3months

Copy link
Copy Markdown
Member

고생하셨습니다 👍

@i3months i3months merged commit 252efac into dev May 15, 2026
2 checks passed
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.

2 participants