-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor auth API with Redis token management and service separation #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
7de1a71
91da6da
f489ff6
7fb8ed2
6ad5d99
b550cc2
fe986c1
5725a46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,4 @@ out/ | |
| /.nb-gradle/ | ||
|
|
||
| ### VS Code ### | ||
| .vscode/ | ||
|
|
||
| ### QueryDSL ### | ||
| src/main/generated/ | ||
| .vscode/ | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,122 @@ | ||||||||||
| # Redis 로컬 개발 환경 접속 가이드 (with AWS ElastiCache) | ||||||||||
|
|
||||||||||
| > 본 문서는 **VPC 내 ElastiCache Redis**에 대해, 로컬 개발 환경에서도 운영 환경과 동일한 방식으로 접근할 수 있도록 포트 포워딩 기반 개발 흐름을 정리한 가이드입니다. | ||||||||||
| > Bastion Host를 별도로 구성하지 않고, **기존 EC2 인스턴스를 SSM 포워딩 노드로 활용**합니다. | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| ## ✅ 개요 | ||||||||||
|
|
||||||||||
| | 항목 | 내용 | | ||||||||||
| |-------------|-------------------------------------------------------| | ||||||||||
| | 대상 Redis | AWS ElastiCache for Redis (Private Subnet) | | ||||||||||
| | 접근 방식 | AWS Systems Manager - `PortForwardingSession` 사용 | | ||||||||||
| | 중계 노드 | 동일 VPC 내 EC2 인스턴스 (SSM Agent 연결 상태 필요) | | ||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ## 1. 요구 사항 | ||||||||||
|
|
||||||||||
| ### 1.1 사전 조건 | ||||||||||
|
|
||||||||||
| - AWS CLI 설치 및 `configure` 완료 | ||||||||||
| - EC2 인스턴스에 **SSM Agent 설치 + IAM Role 연결**되어 있어야 함 | ||||||||||
| - Redis와 EC2는 동일 VPC/Subnet 내 존재 | ||||||||||
| - Redis 보안 그룹에 EC2 인스턴스 허용 설정 | ||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ## 2. 설정 단계 | ||||||||||
|
|
||||||||||
| ### 2.1 AWS CLI 인증 구성 | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| aws configure --profile dev-redis | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| - Access Key, Secret, Region 입력 | ||||||||||
| - 사용 목적에 맞게 별도 프로파일 구성 권장 | ||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ### 2.2 EC2 인스턴스를 통한 포트 포워딩 | ||||||||||
|
|
||||||||||
| 1. EC2 인스턴스 ID 확인 (`i-xxxxxxxxxxxxxxxxx`) | ||||||||||
| 2. SSM 포트 포워딩 세션 실행: | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| aws ssm start-session \ | ||||||||||
| --target i-xxxxxxxxxxxxxxxxx \ | ||||||||||
| --document-name AWS-StartPortForwardingSession \ | ||||||||||
| --parameters '{"portNumber":["6379"],"localPortNumber":["6379"]}' \ | ||||||||||
| --profile dev-redis | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| > 이 세션이 유지되는 동안 `localhost:6379`는 EC2 내부 Redis 포트에 직접 연결된 것과 동일하게 동작합니다. | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| ### 2.3 연결 확인 | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| valkey-cli --tls -h localhost -p 6379 ping | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| 정상적으로 `PONG` 응답이 오면 연결 성공입니다. | ||||||||||
|
Comment on lines
+61
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I pity the fool who uses the wrong Redis client! valkey-cli ain't standard! Redis 연결 확인 명령어에 문제가 있습니다:
```bash
-valkey-cli --tls -h localhost -p 6379 ping
+redis-cli --tls -h localhost -p 6379 ping또는 TLS 설정에 따라: redis-cli -h localhost -p 6379 ping대부분의 환경에서는 🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ### 2.4 Spring Boot 환경 구성 예시 | ||||||||||
|
|
||||||||||
| ```yaml | ||||||||||
| spring: | ||||||||||
| data: | ||||||||||
| redis: | ||||||||||
| host: localhost | ||||||||||
| port: 6379 | ||||||||||
| ssl: | ||||||||||
| enabled: true | ||||||||||
| ``` | ||||||||||
| - 운영/로컬 환경 모두 동일 구성 사용 | ||||||||||
| - 운영에서는 EC2 → Redis 직접 연결 | ||||||||||
| - 로컬에서는 포트포워딩 세션을 통해 동일 흐름 유지 | ||||||||||
| --- | ||||||||||
| ## 3. Redis 연결 트러블슈팅 | ||||||||||
| ### 3.1 systemd 기반 socat 포워딩 관리 (옵션) | ||||||||||
| ```bash | ||||||||||
| sudo systemctl daemon-reexec | ||||||||||
| sudo systemctl daemon-reload | ||||||||||
| sudo systemctl enable socat-redis | ||||||||||
| sudo systemctl start socat-redis | ||||||||||
| sudo systemctl status socat-redis | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| - 서비스 로그 확인: | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| journalctl -u socat-redis | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ## 4. 자주 발생하는 이슈 | ||||||||||
|
|
||||||||||
| | 증상 | 원인 및 해결 방안 | | ||||||||||
| |----------------------------------|------------------------------------------------------------------------------------| | ||||||||||
| | `Timeout` 또는 연결 안됨 | - SSM 세션이 종료되었거나<br>- Redis 보안 그룹에서 EC2 인바운드 허용 누락 | | ||||||||||
| | 포워딩 명령어 실행 시 오류 발생 | - EC2에 SSM Agent 미설치<br>- IAM Role에 `ssm:StartSession` 권한 미설정<br>- AWS CLI 인증 오류 | | ||||||||||
| | 데이터가 깨져 보임 | - Redis 클러스터 모드 사용 중<br>- Lettuce 클라이언트 설정을 클러스터 대응으로 변경 필요 | | ||||||||||
|
|
||||||||||
| --- | ||||||||||
|
|
||||||||||
| ## 📎 참고 자료 | ||||||||||
|
|
||||||||||
| - [AWS Blog - Port Forwarding with SSM to ElastiCache Redis](https://aws.amazon.com/blogs/mt/aws-systems-manager-session-manager-port-forwarding-to-amazon-elasticache-redis-inside-private-subnet/) | ||||||||||
| - [PR #139](https://github.com/juulabel/juulabel-back/pull/141): 인증 전략 개선 및 Redis 기반 세션 관리 적용 상세 내역 | ||||||||||
|
Comment on lines
+119
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I pity the fool who gives wrong PR references! Fix that link! 참조 링크에 오류가 있습니다: -- [PR #139](https://github.com/juulabel/juulabel-back/pull/141): 인증 전략 개선 및 Redis 기반 세션 관리 적용 상세 내역
+- [PR #141](https://github.com/juulabel/juulabel-back/pull/141): 인증 전략 개선 및 Redis 기반 세션 관리 적용 상세 내역PR 번호와 URL이 일치하지 않습니다. 현재 PR이 #141이므로 텍스트도 #141로 수정해야 합니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| --- | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| # Auth API 리팩터링 및 인증 전략 고도화 (PR [#139](https://github.com/juulabel/juulabel-back/pull/141)) | ||
|
|
||
| ## 📌 Summary | ||
|
|
||
| 이 PR은 인증 모듈을 보안 중심의 구조로 리디자인하고, 유지보수성 및 확장성을 고려한 API 명세 리팩터링을 포함합니다. 주요 목표는 다음과 같습니다: | ||
|
|
||
| - 인증 API 도메인의 **명확한 경계 설정** | ||
| - **Refresh Token Rotation** 전략 기반의 인증 안정성 확보 | ||
| - **서버 측 세션 관리**로 클라이언트 신뢰 수준 최소화 | ||
| - **비정상 로그인 탐지 기반 확장**을 고려한 로깅 구조 설계 | ||
|
|
||
| --- | ||
|
|
||
| ## 1. 구조 리팩터링: 인증 도메인 책임 분리 | ||
|
|
||
| 기존 API는 `/members` 하위에 인증과 사용자 관리 로직이 혼재되어 있어, 도메인 분리에 따른 유지보수 비용이 컸습니다. 다음과 같이 명확히 분리합니다: | ||
|
|
||
| | 기존 경로 | 신규 경로 | 목적 | | ||
| | ------------------------- | ---------------------- | ---------------------------- | | ||
| | `/v1/api/members/login` | `/v1/api/auth/login` | 인증 도메인 분리 | | ||
| | `/v1/api/members/sign-up` | `/v1/api/auth/sign-up` | | | ||
| | `/v1/api/members/me` | `/v1/api/auth/me` | | | ||
| | _(신규)_ | `/v1/api/auth/refresh` | Refresh Token 재발급 | | ||
| | _(신규)_ | `/v1/api/auth/logout` | 서버 측 로그아웃 (세션 종료) | | ||
|
|
||
| 💡 **Outcome:** 인증 흐름과 사용자 정보 흐름의 경계가 명확해져 API 소비자 및 테스트 범위가 선명해집니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 2. Refresh Token 기반 인증 및 Rotation 전략 | ||
|
|
||
| ### Why Rotation? | ||
|
|
||
| 토큰 도난 시, 고정 Refresh Token 구조는 **세션 탈취 리스크**를 증가시킵니다. 이에 따라 Rotation 전략을 적용합니다. | ||
|
|
||
| ### 동작 방식 | ||
|
|
||
| - Access Token 만료 시 `/auth/refresh` 호출 → 새 Access + Refresh Token 응답 | ||
| - 이전 Refresh Token은 **즉시 폐기** 및 Redis 블랙리스트 등록 | ||
| - 동일 토큰 재사용 시 → 인증 실패 (401) | ||
|
|
||
| 💡 **보안 장점:** 사용된 토큰은 재사용 불가 → 리플레이 공격 방지 강화 | ||
|
|
||
| --- | ||
|
|
||
| ## 3. 비정상 로그인 탐지 기반 확장 고려 | ||
|
|
||
| ### 수집 항목 | ||
|
|
||
| - `Device-Id` (필수 헤더) | ||
| - User-Agent, IP (서버 로그 자동 수집) | ||
|
|
||
| 이 정보는 향후 다음 기능에 활용됩니다: | ||
|
|
||
| - 동일 계정 다중 위치/디바이스 로그인 탐지 | ||
| - 의심 활동에 대한 보안 알림 트리거 | ||
| - 로그인 히스토리 시각화 | ||
|
|
||
| 💡 **시사점:** 인증은 단일 절차가 아닌 보안 트래픽의 출발점이며, 메타데이터 수집이 이후 기능 확장의 기반이 됩니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 4. 로그아웃: 서버 중심 세션 종료 방식으로 전환 | ||
|
|
||
| 기존 구조는 클라이언트 측에서 Access Token 제거만으로 로그아웃 처리하였습니다. | ||
| 새로운 구조에서는 명시적 로그아웃 API 호출로 다음 동작 수행: | ||
|
|
||
| - Redis에 등록된 Refresh Token을 블랙리스트화 | ||
| - 이후 해당 토큰 사용 시 인증 실패 | ||
|
|
||
| 💡 **효과:** 토큰 재사용 방지 → 클라이언트 신뢰도 최소화 | ||
|
|
||
| --- | ||
|
|
||
| ## 5. Redis 기반 토큰 관리 및 인프라 구성 | ||
|
|
||
| | 항목 | 내용 | | ||
| | ----------- | ---------------------------------------------------- | | ||
| | 저장소 구성 | AWS ElastiCache (Valkey) | | ||
| | 접근 방식 | VPC 내부 `socat + SSM 포트포워딩` 기반 접속 | | ||
| | 라이브러리 | `spring-data-redis (lettuce)` | | ||
| | 관리 전략 | TTL 기반 자동 만료 + Lua Script 기반 블랙리스트 삽입 | | ||
|
|
||
| 💡 **운영 이점:** Redis는 고성능 키-밸류 스토어로써 세션 상태 관리에 적합하며, Lua Script로 atomic 블랙리스트 처리 가능 | ||
|
|
||
| --- | ||
|
|
||
| ## 6. 적용 시 유의사항 | ||
|
|
||
| | 항목 | 설명 | | ||
| | -------------------------------------------- | --------------------------------------------------------- | | ||
| | `Device-Id` 누락 시 400 반환 | 모든 인증 요청 시 필수 포함 필요 | | ||
| | `/auth/logout` 미호출 시 Refresh 무효화 누락 | 클라이언트에서만 로그아웃 처리 시 토큰은 유효 상태 유지됨 | | ||
| | `/members/*` 인증 경로 사용 중단 | 호출 시 404 응답 발생 가능성 있음. 즉시 경로 전환 필요 | | ||
|
|
||
| --- |
This file was deleted.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.