Skip to content

feature: 임시 로그인 추가#135

Open
ykmxxi wants to merge 2 commits into
v2/developfrom
v2/feature/#134-temporary-login
Open

feature: 임시 로그인 추가#135
ykmxxi wants to merge 2 commits into
v2/developfrom
v2/feature/#134-temporary-login

Conversation

@ykmxxi

@ykmxxi ykmxxi commented Jul 17, 2026

Copy link
Copy Markdown

연관된 이슈

변경 사항

  • POST /auth/login/dev 개발용 임시 로그인 API를 추가했습니다.
  • 카카오 로그인 없이도 설정된 고정 아이디/비밀번호로 로그인해 로컬·개발 환경에서 인증이 필요한 API를 테스트할 수 있게 했습니다.
  • 로그인 성공 시 카카오 로그인과 동일하게 Forgather access token과 refresh token을 응답 바디와 HttpOnly 쿠키로 함께 반환합니다.
  • 최초 로그인 시 임시 계정을 자동 생성하고, 실제 온보딩 로직(AuthService.submitOnboarding)을 재사용해 온보딩이 완료된 상태로 만듭니다.
  • 고정 크리덴셜 비교는 타이밍 공격에 안전한 상수 시간 비교(MessageDigest.isEqual)로 구현했습니다.
  • 임시 로그인 설정값 auth.dev-login.login-id, auth.dev-login.password, auth.dev-login.nickname을 추가하고 환경별 설정을 구성했습니다.
  • 임시 로그인 관련 컴포넌트를 @Profile({"local", "dev", "test"})로 제한해 운영(prod) 환경에는 등록되지 않도록 격리했습니다.
  • 운영 환경 노출을 막는 프로파일 가드 회귀 테스트와 로그인 흐름 인수 테스트를 추가했습니다.

작업 내용

API

POST /auth/login/dev

설정 파일에 지정된 고정 아이디/비밀번호로 로그인합니다. 카카오 로그인과 동일하게 Forgather access token과 refresh token을 응답 바디와 HttpOnly 쿠키로 함께 반환합니다.

로컬·개발·테스트 프로파일에서만 등록되며, 운영 환경에는 이 엔드포인트가 존재하지 않습니다.

[요청]

위치 파라미터 타입 설명
Body loginId string 설정된 개발용 임시 로그인 아이디
Body password string 설정된 개발용 임시 로그인 비밀번호

[요청 예시]

{
  "loginId": "your-dev-login-id",
  "password": "your-dev-login-password"
}

[응답]

상태 코드 code 설명
200 SUCCESS 임시 로그인 성공
401 UNAUTHORIZED 아이디 또는 비밀번호 불일치

[응답 예시 - 200]

{
  "code": "SUCCESS",
  "message": null,
  "data": {
    "accessToken": "forgather-access-token",
    "refreshToken": "forgather-refresh-token"
  }
}

[응답 쿠키]

쿠키 Path HttpOnly
access_token / true
refresh_token /auth/refresh true

기존 카카오 로그인 및 토큰 재발급 API와 동일한 AuthCookieProvider 정책(secure/SameSite/만료 시간)을 적용합니다. 쿠키 만료 시간은 각 토큰의 잔여 만료 시간으로 설정합니다.


크리덴셜 검증

[인증 기준]

설정된 auth.dev-login.login-id, auth.dev-login.password와 요청 값이 모두 일치할 때만 로그인에 성공합니다. 하나라도 불일치하면 UnauthorizedException으로 401을 반환합니다.

[상수 시간 비교]

아이디·비밀번호 비교는 MessageDigest.isEqual을 사용해 상수 시간으로 수행합니다. 문자열 조기 반환 비교에서 발생할 수 있는 타이밍 사이드채널을 피하기 위함입니다.

[평문 비밀번호 로깅 방지]

LoggingAspect가 서비스 메서드 파라미터를 toString()으로 로깅하므로, DevLoginRequest.toString()을 재정의해 비밀번호를 ***로 마스킹합니다. 이 재정의를 제거하면 평문 비밀번호가 app.log에 남습니다.


회원 처리

[신규 회원]

설정된 login-id에 연결된 임시 계정이 없으면 다음을 수행합니다.

  • login-id를 식별자로 하는 KakaoHost를 생성합니다.
  • Host.name은 설정된 auth.dev-login.nickname으로 저장합니다.
  • 실제 온보딩 로직(AuthService.submitOnboarding)을 그대로 재사용해 필수 약관에 동의하고 온보딩을 완료 처리합니다.

실제 온보딩 경로를 재사용하므로 임시 로그인 계정과 실제 계정의 상태가 갈라지지 않습니다.

[기존 회원]

이미 생성된 임시 계정은 login-id로 조회해 재사용하며, 로그인 시마다 계정 정보를 갱신하거나 약관 동의 이력을 중복 저장하지 않습니다.

[Forgather 토큰]

회원 확인 또는 생성이 완료되면 Forgather access token과 refresh token을 발급해 기존 LoginResponse 응답 바디와 HttpOnly 쿠키에 함께 담아 반환합니다.

임시 로그인이 사용되면 경고 로그(개발용 임시 로그인이 사용되었습니다.)를 남깁니다.


운영 환경 격리 (프로파일)

임시 로그인 관련 컴포넌트를 local, dev, test 프로파일에서만 등록되도록 제한했습니다.

  • DevAuthController — 엔드포인트 자체가 운영 환경에 매핑되지 않습니다.
  • DevAuthService — 인증·회원 처리 빈이 운영 환경에 등록되지 않습니다.
  • DevLoginProperties — 설정 프로퍼티 빈이 운영 환경에 등록되지 않습니다. (@ConfigurationPropertiesScan으로 스캔되므로 프로퍼티 클래스에 붙인 @Profile이 그대로 적용됩니다.)

세 컴포넌트가 동일한 {"local", "dev", "test"} 프로파일 집합으로 함께 등록·제외되며, 운영 환경에서는 임시 로그인 진입 경로가 존재하지 않습니다.


설정

[auth.dev-login]

환경별 설정에 임시 로그인 값을 추가했습니다.

  • auth.dev-login.login-id — 임시 로그인 아이디
  • auth.dev-login.password — 임시 로그인 비밀번호
  • auth.dev-login.nickname — 최초 생성 시 사용할 닉네임

로컬(application.yml), 개발 서버(application-dev.yml), 테스트(src/test/resources/application.yml) 프로파일에 각각 값을 구성했습니다. 실제 크리덴셜 값은 git-crypt로 암호화된 설정 파일에서 관리하며, 본 문서에는 예시 placeholder로 대체했습니다.


테스트

[프로파일 가드 회귀 테스트]

DevAuthProfileGuardTestprod 프로파일에서는 DevAuthController, DevAuthService 빈이 등록되지 않음을 검증합니다. 화이트리스트({"local","dev","test"})를 블랙리스트(!prod)로 바꾸는 등의 사고로 운영 환경에 임시 로그인이 노출되는 회귀를 막습니다.

[인수 테스트]

DevAuthAcceptanceTesttest 프로파일 전체 컨텍스트에서 로그인 엔드포인트를 검증합니다.

  • 고정 아이디/비밀번호로 로그인하면 토큰을 바디와 쿠키(2개)로 함께 반환한다.
  • 임시 로그인으로 발급받은 토큰으로 내 정보를 조회하면 온보딩이 완료되어 있다.
  • 비밀번호가 일치하지 않으면 로그인할 수 없다(401).
  • 아이디가 일치하지 않으면 로그인할 수 없다(401).
  • 두 번 로그인해도 같은 호스트를 재사용하고 약관 동의 이력을 중복 저장하지 않는다.

제외 범위

  • 운영(prod) 환경 임시 로그인 지원
  • 임시 로그인 계정과 실제 카카오 계정의 연결/병합
  • 다중 임시 계정 및 동적 크리덴셜 관리

Summary by CodeRabbit

  • 새 기능
    • 로컬·개발·테스트 환경에서만 동작하는 개발용 임시 로그인 API를 추가했습니다.
    • 로그인 성공 시 액세스·리프레시 토큰이 응답에 포함되고, HttpOnly 쿠키로도 함께 발급됩니다.
    • 최초 로그인 시 자동으로 호스트 생성 및 온보딩(약관 동의) 처리가 완료됩니다.
  • 보안
    • 운영 환경에서는 비활성화되며, 비밀번호는 로그에서 마스킹됩니다.
  • 테스트
    • 토큰/쿠키 발급, 온보딩 완료, 잘못된 자격 증명(401), 중복 저장 방지까지 검증합니다.

@ykmxxi ykmxxi self-assigned this Jul 17, 2026
@ykmxxi ykmxxi added the feature label Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "tools"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3013f4ce-9919-4a09-a9fe-9bca7af812b2

📥 Commits

Reviewing files that changed from the base of the PR and between c1afb60 and 48aaa19.

📒 Files selected for processing (1)
  • src/main/java/com/forgather/global/auth/dev/DevLoginProperties.java

📝 Walkthrough

Walkthrough

개발·로컬·테스트 프로필에서만 활성화되는 /auth/login/dev API가 추가되었습니다. 설정된 자격 증명을 검증한 뒤 호스트를 조회하거나 생성하고, 필수 약관 온보딩과 access/refresh JWT 발급을 수행합니다. 응답 본문과 HttpOnly 쿠키에 토큰을 반환합니다. 성공·실패 로그인, 온보딩 상태, 중복 데이터 방지 및 프로덕션 프로필 비활성화를 검증하는 테스트와 테스트 설정이 추가되었습니다.


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.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a temporary login feature for development and testing environments (under 'local', 'dev', and 'test' profiles), allowing authentication with fixed credentials. It includes the controller, service, configuration properties, request DTO, and comprehensive acceptance and profile guard tests. Feedback on the changes suggests adding a null check for the expected credentials in DevAuthService to prevent a potential NullPointerException, and applying the profile restriction to DevLoginProperties to avoid registering it as a bean in production.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/main/java/com/forgather/global/auth/dev/DevAuthService.java
Comment thread src/main/java/com/forgather/global/auth/dev/DevLoginProperties.java
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Test Results

 97 files  +2   97 suites  +2   1m 2s ⏱️ -4s
614 tests +6  614 ✅ +6  0 💤 ±0  0 ❌ ±0 
644 runs  +6  644 ✅ +6  0 💤 ±0  0 ❌ ±0 

Results for commit 48aaa19. ± Comparison against base commit c3dd913.

This pull request removes 15 and adds 21 tests. Note that renamed tests count towards both.
com.forgather.domain.model.SoftDeleteEntityTest ‑ [1] entity=com.forgather.domain.space.model.Space@379614be
com.forgather.domain.model.SoftDeleteEntityTest ‑ [2] entity=com.forgather.domain.space.model.SpacePhoto@122e4e2f
com.forgather.domain.model.SoftDeleteEntityTest ‑ [2] entity=com.forgather.domain.space.model.SpacePhoto@7a08611c
com.forgather.domain.model.SoftDeleteEntityTest ‑ [3] entity=com.forgather.global.auth.model.SpaceHost@208c918d
com.forgather.domain.model.SoftDeleteEntityTest ‑ [3] entity=com.forgather.global.auth.model.SpaceHost@692ac8d
com.forgather.domain.model.SoftDeleteEntityTest ‑ [4] entity=com.forgather.domain.guestbook.model.GuestBookCard@40321e13
com.forgather.domain.model.SoftDeleteEntityTest ‑ [4] entity=com.forgather.domain.guestbook.model.GuestBookCard@76c523a2
com.forgather.domain.model.SoftDeleteEntityTest ‑ [5] entity=com.forgather.domain.guestbook.model.GuestBookCardPhoto@172ac29d
com.forgather.domain.model.SoftDeleteEntityTest ‑ [5] entity=com.forgather.domain.guestbook.model.GuestBookCardPhoto@40d3ad1a
com.forgather.domain.model.SoftDeleteEntityTest ‑ [6] entity=com.forgather.domain.product.model.Product@7795b961
…
com.forgather.acceptance.DevAuthAcceptanceTest ‑ 고정 아이디와 비밀번호로 로그인하면 카카오 로그인과 동일하게 토큰을 바디와 쿠키로 함께 반환한다
com.forgather.acceptance.DevAuthAcceptanceTest ‑ 두 번 로그인해도 같은 호스트를 재사용하고 약관 동의 이력을 중복 저장하지 않는다
com.forgather.acceptance.DevAuthAcceptanceTest ‑ 비밀번호가 일치하지 않으면 로그인할 수 없다
com.forgather.acceptance.DevAuthAcceptanceTest ‑ 아이디가 일치하지 않으면 로그인할 수 없다
com.forgather.acceptance.DevAuthAcceptanceTest ‑ 임시 로그인으로 발급받은 토큰으로 내 정보를 조회하면 온보딩이 완료되어 있다
com.forgather.domain.model.SoftDeleteEntityTest ‑ [1] entity=com.forgather.domain.space.model.Space@1bab8268
com.forgather.domain.model.SoftDeleteEntityTest ‑ [2] entity=com.forgather.domain.space.model.SpacePhoto@1a2ab495
com.forgather.domain.model.SoftDeleteEntityTest ‑ [2] entity=com.forgather.domain.space.model.SpacePhoto@6ca0fdd0
com.forgather.domain.model.SoftDeleteEntityTest ‑ [3] entity=com.forgather.global.auth.model.SpaceHost@1a7453a0
com.forgather.domain.model.SoftDeleteEntityTest ‑ [3] entity=com.forgather.global.auth.model.SpaceHost@3eefaa11
…

♻️ This comment has been updated with latest results.

@ykmxxi
ykmxxi requested a review from kjyyjk July 18, 2026 07:20

@kjyyjk kjyyjk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

고생하셨습니다!
코멘트 답변만 달아주시고 머지하셔도 됩니다

Comment on lines +66 to +69
return MessageDigest.isEqual(
input.getBytes(StandardCharsets.UTF_8),
expected.getBytes(StandardCharsets.UTF_8)
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

String.equals와 같이 단순 문자열 비교를 하지 않은 이유가 있나요?

Comment on lines +9 to +13
/**
* 개발용 임시 로그인이 운영 환경에 노출되지 않는지 검증한다.
* @Profile을 화이트리스트({"local","dev","test"})가 아닌 블랙리스트(!prod)로 바꾸는 사고를 막는 회귀 테스트다.
*/
@DisplayName("프로파일 가드: 개발용 임시 로그인")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

👍

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.

feature: 임시 로그인 추가

2 participants