배경
구름톤 딥다이브에서 PM, PD, FE, BE 총 4개의 직군이 협업하여 5주 동안 프로젝트를 제작하였습니다. 본 문서는 프로젝트의 핵심 기능인 인증/인가 시스템에 대한 기술 명세를 다룹니다.
1. 서비스 소개
여행 계획 서비스의 주요 차별점은 비로그인 사용자도 손쉽게 접근하고 협업할 수 있는 기능입니다. 기존 서비스들의 높은 진입 장벽(필수 회원가입)을 해결하여 즉각적인 협업이 가능한 서비스를 구현하였습니다.
1.1 문제 정의
- 대부분의 여행 계획 서비스들은 로그인한 사용자만 접근 가능
- 여행 계획을 공유하려면 상대방도 회원가입이 필요
- 즉석에서 계획을 보거나 수정하기 어려움
1.2 해결해야 할 문제
- 비로그인 사용자의 접근성 제한
- 불필요한 회원가입으로 인한 사용자 이탈
- 즉각적인 협업의 어려움
- 외부 공유의 번거로움
1.3 개발환경 및 인프라
기술 스택
- Backend Framework: Spring Boot 3.5.4
- Java Version: Java 21
- Database:
- Primary: MySQL 8.0.42
- Cache: Redis 7.2
- Security:
- Spring Security
- JWT (0.11.5)
- API Documentation:
- Springdoc OpenAPI (Swagger) 2.8.10
- ORM & Query:
- Spring Data JPA
- Querydsl 6.11
- Monitoring:
- Spring Actuator
- Prometheus/Micrometer
- Testing:
개발 및 배포 환경
-
로컬 개발 환경
- Docker Compose를 활용한 컨테이너 관리
- MySQL(3306), Redis(6379) 포트 매핑
-
테스트 환경
- Testcontainers를 활용한 통합 테스트
- GitHub Actions CI/CD 파이프라인
-
모니터링 시스템
- Actuator 엔드포인트 활용
- Prometheus 메트릭스 수집
- JWT (JSON Web Token) 0.11.5
- API Documentation: SpringDoc OpenAPI (Swagger) 2.8.10
- ORM:
- Spring Data JPA
- Querydsl 6.11
- Monitoring:
- Spring Actuator
- Prometheus
- Testing:
- JUnit
- Spring Boot Test
- Testcontainers
인프라 구성
- 컨테이너화: Docker Compose를 통한 로컬 개발 환경 구성
- 데이터베이스 구성:
- MySQL: 3306 포트
- Redis: 6379 포트
- CI/CD: GitHub Actions를 통한 자동화된 빌드 및 테스트
2. 설계
2.1 기획 요구사항 분석
- 세분화된 권한 체계:
- 총 5개 ROLE [Owner, Member, Traveler, Guest, Viewer]
- 각 역할별 차등적 권한 부여
- URL 기반 공유 시스템:
- 간편한 공유 링크 생성
- 권한별 차별화된 링크 생성
- 비로그인 접근 지원:
- Traveler, Guest 역할은 링크를 통한 비로그인 접근 가능
- 보안 체계:
- 초대자가 생성한 링크를 통해서만 접근 가능
- 링크의 유효성 검증
2.2 권한 체계 상세

2.3 개발자 관점 요구사항
- 통합된 인증 플로우:
- 로그인/비로그인 사용자를 위한 단일 인증 흐름
- 코드 복잡도 최소화
- Role 기반 접근 제어:
- 각 API 엔드포인트별 최소 필요 Role 정의
- Spring Security의 @PreAuthorize 활용
- 코드 품질:
- 기술 스택 활용:
- Spring Security와 JWT의 효율적 통합
- Redis를 활용한 토큰 관리
2.4 인가(Authorization) 계층
Team 레벨
└── Owner/Member (팀의 모든 프로젝트 접근/편집)
└── Project 레벨
└── Traveler (특정 프로젝트 접근/편집)
└── 외부 접근 레벨
├── Guest (읽기/쓰기)
└── Viewer (읽기 전용)
3. 구현 방식 비교 분석
3.1 게스트 계정 생성 방식

구현 방법
-
게스트 계정 생성 프로세스
- 프로젝트 ID와 권한 레벨에 따른 게스트 계정 생성
- 임시 비밀번호 생성 및 암호화 저장
- 게스트 계정 메타데이터 (생성 시간, 마지막 접속 등) 기록
- 초대 이메일 전송 및 접속 정보 전달
-
권한 관리 시스템
- Spring Security의 UserDetails 인터페이스 구현
- 역할 기반 권한 관리 (RBAC) 적용
- 세션 관리 및 자동 만료 처리
-
데이터 관리 메커니즘
- JPA 엔티티 관계 설정 (프로젝트-게스트 매핑)
- 자동 데이터 정리 (Scheduled 태스크)
- 사용자 활동 로깅 및 추적
장단점 분석
장점
- 기존 인증 시스템 활용 가능
- 사용자 행동 추적 용이
- 권한 관리 용이
- 세부적인 액세스 컨트롤 가능
단점
- 불필요한 계정 데이터 증가
- 임시 계정 관리 부담
- DB 의존도가 높음
- 스케일링 시 관리 복잡성 증가
보안 강화 방안
-
계정 보안
- 정기적인 비밀번호 만료 및 갱신
- 접속 IP 제한 및 모니터링
- 비활성 계정 자동 정리
-
데이터 보호
- 게스트 데이터 암호화 저장
- 접근 로그 기록 및 감사
- 데이터 백업 및 복구 정책
3.2 일회용 토큰 방식

구현 방법
-
토큰 생성 프로세스
- 프로젝트 ID, 권한 레벨, 유효기간을 포함한 JWT 토큰 생성
- 난수화된 토큰 ID 및 서명 추가
- Redis에 토큰 메타데이터 저장 (사용 횟수, 생성자 정보 등)
- 초대 URL 생성 및 전송
-
토큰 검증 시스템
- Redis에서 토큰 유효성 검사
- JWT 서명 및 만료 시간 검증
- 사용 횟수 추적 및 제한 처리
-
상태 관리 메커니즘
- Redis TTL을 활용한 자동 만료 처리
- 토큰 사용 현황 모니터링
- 비정상 접근 탐지 및 차단
장단점 분석
장점
- 높은 보안성
- 사용 횟수 제한 가능
- 토큰 즉시 무효화 가능
- 세부적인 액세스 컨트롤
단점
- Redis 의존성
- 토큰 관리 복잡성
- 재사용 불가능
- 인프라 운영 비용 증가
보안 강화 방안
-
토큰 보안
- 암호화 방식의 정기적 업데이트
- 이중 인증 옵션 제공
- 토큰 사용 패턴 분석
-
시스템 보호
- Redis 클러스터링 구성
- 데이터 독립성 보장
- 재난 복구 전략 수립
3.3 링크 공유 방식 (채택)

구현 방법
-
링크 생성 프로세스
- 프로젝트 ID와 권한 레벨(Guest/Viewer)을 포함한 페이로드 생성
- 시스템 비밀키를 사용하여 페이로드에 대한 HMAC 서명 생성
- 만료 시간을 포함한 타임스탬프 추가
- 페이로드, 서명, 타임스탬프를 Base64로 인코딩하여 단일 문자열로 변환
-
링크 검증 프로세스
- 수신된 링크를 Base64 디코딩하여 구성 요소 분리
- 타임스탬프 검사로 만료 여부 확인
- 시스템 비밀키로 HMAC 서명 재계산하여 위변조 검증
- 프로젝트 ID와 권한 레벨 추출하여 접근 권한 부여
-
권한 관리 메커니즘
- Spring Security의 커스텀 필터를 통해 링크 기반 인증 처리
- ThreadLocal에 추출된 권한 정보 저장
- @PreAuthorize 어노테이션으로 각 API 엔드포인트 보호
장단점 분석
장점
- 인프라 의존성 없는 Stateless 방식
- 기존 API 재사용 가능
- 수평적 확장 용이
- 구현 및 유지보수 간편
- 서버 부하 최소화
단점
- 브라우저 히스토리에 노출
- 공유 링크 회수 어려움
- 접근 기록 추적 제한적
- 실시간 권한 변경 어려움
보안 강화 방안
-
링크 보안
- 짧은 만료 시간 설정 (기본 24시간)
- 복잡한 난수를 포함한 URL 생성
- HTTPS 필수 적용
-
접근 제어
- IP 기반 접근 제한
- 동시 접속 제한
- 비정상 패턴 감지 및 차단
4. 보안 및 구현 고려사항
4.1 링크 보안
- 만료 시간 설정: 모든 공유 링크에 유효 기간 설정
- 서명 검증: HMAC을 이용한 링크 무결성 검증
- Rate Limiting: IP 기반 접근 제한
4.2 권한 관리 및 구현 상세
-
권한 관리 원칙
@PreAuthorize("hasRole('OWNER') or hasRole('MEMBER')")
@GetMapping("/projects/{projectId}")
public ProjectResponse getProject(@PathVariable Long projectId) {
}
-
계층형 권한 검증
- Controller: @PreAuthorize 어노테이션
- Service: Custom SecurityUtil 활용
- Repository: 연관 관계 기반 검증
-
인증 필터 처리
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain) {
}
}
4.3 데이터 보안 및 유효성 검증
-
입력 값 검증
@Validated
@RequestBody ProjectCreateRequest request {
@NotBlank
@Size(max = 100)
private String title;
@NotNull
@Future
private LocalDateTime startDate;
}
-
XSS 방지
- HTML 이스케이프 처리
- Content-Security-Policy 적용
-
API 요청 유효성
- Rate Limiting 적용
- 요청 크기 제한
- 인증 헤더 검증
5. 결론 및 향후 계획
5.1 핵심 의사결정 사항
-
링크 공유 방식 채택 이유
- 높은 확장성과 단순한 아키텍처
- 최소한의 인프라 의존성
- 사용자 경험 최적화
- 비용 효율적인 운영 가능
- 실시간 모니터링 용이
-
보안과 편의성의 균형
- JWT + HMAC 기반의 안전한 서명
- Actuator + Prometheus를 활용한 실시간 모니터링
- 세부적인 로깅 및 추적 기능
-
보안과 편의성의 균형
- 24시간 제한의 링크 유효기간
- 권한별 차등적 접근 제어
- 간편한 공유 프로세스
5.2 향후 개선 계획
-
단기 개선사항 (1-2개월)
- 링크 관리 대시보드 구현
- 접근 로그 시스템 강화
- 실시간 알림 기능 추가
-
중장기 계획 (3-6개월)
- 실시간 권한 변경 기능 구현
- OAuth 기반 소셜 로그인 통합
- 분석 대시보드 개발
5.3 모니터링 및 유지보수
-
시스템 모니터링
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
application: moyeohaeng
-
성능 측정 메트릭스
- API 응답 시간 (Timer)
- 동시 사용자 수 (Gauge)
- 에러 빈도 (Counter)
-
로그 추적
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
log.error("Unexpected error", e);
}
}
-
트러블슈팅 가이드
- 자주 발생하는 이슈 및 해결 방법
- 성능 병목 해결 가이드
- 재난 복구 시나리오
-
운영 가이드
- 시스템 상태 점검 및 정기 점검 절차
- 로그 분석 및 모니터링 전략
- 성능 최적화 가이드
-
확장성 고려사항
- 로드밸런싱 및 스케일아웃 전략
- 캐시 전략 및 Redis 클러스터링
- 데이터베이스 인덱싱 및 최적화
-
보안 모니터링
- 비정상 접근 탐지
- 취약점 정기 점검
- 보안 패치 관리
이 기술 명세서는 프로젝트의 현재 상태를 반영하며, 지속적인 업데이트와 개선이 이루어질 예정입니다. 팀원들의 피드백과 실제 운영 경험을 바탕으로 더 나은 서비스를 제공하기 위해 계속해서 발전시켜 나갈 것입니다.