mirror of
https://github.com/cna-bootcamp/phonebill.git
synced 2025-12-06 08:06:24 +00:00
13 KiB
13 KiB
Auth 서비스 데이터베이스 설계서
1. 설계 개요
1.1 설계 목적
Auth 서비스의 사용자 인증 및 인가 기능 구현을 위한 독립적인 데이터베이스 설계
1.2 설계 원칙
- 서비스 독립성: Auth 서비스 전용 데이터베이스 구성
- 마이크로서비스 패턴: 다른 서비스와 직접적인 FK 관계 없음
- 캐시 우선 전략: 타 서비스 데이터는 Redis 캐시로만 참조
- 보안 강화: 민감 정보 암호화 저장
- 감사 추적: 모든 인증/인가 활동 이력 관리
1.3 주요 기능 요구사항
- UFR-AUTH-010: 사용자 로그인 (ID/Password 인증, 계정 잠금)
- UFR-AUTH-020: 사용자 인가 (서비스별 접근 권한 확인)
2. 데이터베이스 아키텍처
2.1 데이터베이스 정보
- DB 이름:
phonebill_auth - DBMS: PostgreSQL 15
- 문자셋: UTF-8
- 타임존: Asia/Seoul
2.2 서비스 독립성 전략
- 직접 데이터 공유 금지: 다른 서비스 DB와 직접 연결하지 않음
- 캐시 기반 참조: 필요한 외부 데이터는 Redis 캐시를 통해서만 접근
- 이벤트 기반 동기화: 필요 시 메시징을 통한 데이터 동기화
3. 테이블 설계
3.1 사용자 계정 관리
auth_users (사용자 계정)
-- 사용자 기본 정보 및 인증 정보
CREATE TABLE auth_users (
user_id VARCHAR(50) PRIMARY KEY, -- 사용자 ID (로그인 ID)
password_hash VARCHAR(255) NOT NULL, -- 암호화된 비밀번호 (BCrypt)
password_salt VARCHAR(100) NOT NULL, -- 비밀번호 솔트
customer_id VARCHAR(50) NOT NULL, -- 고객 식별자 (외부 참조용)
line_number VARCHAR(20), -- 회선번호 (캐시에서 조회)
account_status VARCHAR(20) DEFAULT 'ACTIVE', -- ACTIVE, LOCKED, SUSPENDED, INACTIVE
failed_login_count INTEGER DEFAULT 0, -- 로그인 실패 횟수
last_failed_login_at TIMESTAMP, -- 마지막 실패 시간
account_locked_until TIMESTAMP, -- 계정 잠금 해제 시간
last_login_at TIMESTAMP, -- 마지막 로그인 시간
last_password_changed_at TIMESTAMP, -- 비밀번호 마지막 변경 시간
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(customer_id)
);
auth_user_sessions (사용자 세션)
-- 사용자 세션 관리
CREATE TABLE auth_user_sessions (
session_id VARCHAR(100) PRIMARY KEY, -- 세션 ID (UUID)
user_id VARCHAR(50) NOT NULL, -- 사용자 ID
session_token VARCHAR(500) NOT NULL, -- JWT 토큰
refresh_token VARCHAR(500), -- 리프레시 토큰
client_ip VARCHAR(45), -- 클라이언트 IP (IPv6 지원)
user_agent TEXT, -- User-Agent 정보
auto_login_enabled BOOLEAN DEFAULT FALSE, -- 자동 로그인 여부
expires_at TIMESTAMP NOT NULL, -- 세션 만료 시간
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES auth_users(user_id) ON DELETE CASCADE
);
3.2 권한 관리
auth_services (서비스 정의)
-- 시스템 내 서비스 정의
CREATE TABLE auth_services (
service_code VARCHAR(30) PRIMARY KEY, -- 서비스 코드
service_name VARCHAR(100) NOT NULL, -- 서비스 이름
service_description TEXT, -- 서비스 설명
is_active BOOLEAN DEFAULT TRUE, -- 서비스 활성화 여부
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
auth_permissions (권한 정의)
-- 권한 정의 테이블
CREATE TABLE auth_permissions (
permission_id SERIAL PRIMARY KEY, -- 권한 ID
service_code VARCHAR(30) NOT NULL, -- 서비스 코드
permission_code VARCHAR(50) NOT NULL, -- 권한 코드
permission_name VARCHAR(100) NOT NULL, -- 권한 이름
permission_description TEXT, -- 권한 설명
is_active BOOLEAN DEFAULT TRUE, -- 권한 활성화 여부
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (service_code) REFERENCES auth_services(service_code),
UNIQUE(service_code, permission_code)
);
auth_user_permissions (사용자 권한)
-- 사용자별 권한 할당
CREATE TABLE auth_user_permissions (
user_permission_id SERIAL PRIMARY KEY, -- 사용자권한 ID
user_id VARCHAR(50) NOT NULL, -- 사용자 ID
permission_id INTEGER NOT NULL, -- 권한 ID
granted_by VARCHAR(50), -- 권한 부여자
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP, -- 권한 만료일 (NULL = 무기한)
is_active BOOLEAN DEFAULT TRUE, -- 권한 활성화 여부
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES auth_users(user_id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES auth_permissions(permission_id),
UNIQUE(user_id, permission_id)
);
3.3 보안 및 감사
auth_login_history (로그인 이력)
-- 로그인 시도 이력
CREATE TABLE auth_login_history (
history_id SERIAL PRIMARY KEY, -- 이력 ID
user_id VARCHAR(50), -- 사용자 ID (실패 시 NULL 가능)
login_type VARCHAR(20) NOT NULL, -- LOGIN, LOGOUT, AUTO_LOGIN
login_status VARCHAR(20) NOT NULL, -- SUCCESS, FAILURE, LOCKED
client_ip VARCHAR(45), -- 클라이언트 IP
user_agent TEXT, -- User-Agent 정보
failure_reason VARCHAR(100), -- 실패 사유
session_id VARCHAR(100), -- 세션 ID (성공 시)
attempted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES auth_users(user_id) ON DELETE SET NULL
);
auth_permission_access_log (권한 접근 로그)
-- 권한 기반 접근 로그
CREATE TABLE auth_permission_access_log (
log_id SERIAL PRIMARY KEY, -- 로그 ID
user_id VARCHAR(50) NOT NULL, -- 사용자 ID
service_code VARCHAR(30) NOT NULL, -- 접근한 서비스
permission_code VARCHAR(50) NOT NULL, -- 확인된 권한
access_status VARCHAR(20) NOT NULL, -- GRANTED, DENIED
client_ip VARCHAR(45), -- 클라이언트 IP
session_id VARCHAR(100), -- 세션 ID
requested_resource VARCHAR(200), -- 요청 리소스
denial_reason VARCHAR(100), -- 거부 사유
accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES auth_users(user_id) ON DELETE CASCADE
);
4. 인덱스 설계
4.1 성능 최적화 인덱스
-- 사용자 조회 최적화
CREATE INDEX idx_auth_users_customer_id ON auth_users(customer_id);
CREATE INDEX idx_auth_users_account_status ON auth_users(account_status);
CREATE INDEX idx_auth_users_last_login ON auth_users(last_login_at);
-- 세션 관리 최적화
CREATE INDEX idx_auth_sessions_user_id ON auth_user_sessions(user_id);
CREATE INDEX idx_auth_sessions_expires_at ON auth_user_sessions(expires_at);
CREATE INDEX idx_auth_sessions_token ON auth_user_sessions(session_token);
-- 권한 조회 최적화
CREATE INDEX idx_auth_user_permissions_user_id ON auth_user_permissions(user_id);
CREATE INDEX idx_auth_user_permissions_active ON auth_user_permissions(user_id, is_active);
CREATE INDEX idx_auth_permissions_service ON auth_permissions(service_code, is_active);
-- 로그 조회 최적화
CREATE INDEX idx_auth_login_history_user_id ON auth_login_history(user_id);
CREATE INDEX idx_auth_login_history_attempted_at ON auth_login_history(attempted_at);
CREATE INDEX idx_auth_permission_log_user_id ON auth_permission_access_log(user_id);
CREATE INDEX idx_auth_permission_log_accessed_at ON auth_permission_access_log(accessed_at);
4.2 보안 관련 인덱스
-- 계정 잠금 관련 조회 최적화
CREATE INDEX idx_auth_users_failed_login ON auth_users(failed_login_count, last_failed_login_at);
CREATE INDEX idx_auth_users_locked_until ON auth_users(account_locked_until) WHERE account_locked_until IS NOT NULL;
-- IP 기반 보안 모니터링
CREATE INDEX idx_auth_login_history_ip_status ON auth_login_history(client_ip, login_status, attempted_at);
5. 제약조건 및 트리거
5.1 데이터 무결성 제약조건
-- 계정 상태 체크 제약조건
ALTER TABLE auth_users ADD CONSTRAINT chk_account_status
CHECK (account_status IN ('ACTIVE', 'LOCKED', 'SUSPENDED', 'INACTIVE'));
-- 로그인 상태 체크 제약조건
ALTER TABLE auth_login_history ADD CONSTRAINT chk_login_status
CHECK (login_status IN ('SUCCESS', 'FAILURE', 'LOCKED'));
-- 로그인 타입 체크 제약조건
ALTER TABLE auth_login_history ADD CONSTRAINT chk_login_type
CHECK (login_type IN ('LOGIN', 'LOGOUT', 'AUTO_LOGIN'));
-- 접근 상태 체크 제약조건
ALTER TABLE auth_permission_access_log ADD CONSTRAINT chk_access_status
CHECK (access_status IN ('GRANTED', 'DENIED'));
5.2 자동 업데이트 트리거
-- updated_at 자동 갱신 함수
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
-- 각 테이블에 updated_at 트리거 적용
CREATE TRIGGER update_auth_users_updated_at BEFORE UPDATE ON auth_users
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_auth_services_updated_at BEFORE UPDATE ON auth_services
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_auth_permissions_updated_at BEFORE UPDATE ON auth_permissions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_auth_user_permissions_updated_at BEFORE UPDATE ON auth_user_permissions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
6. 보안 설계
6.1 암호화 전략
- 비밀번호: BCrypt 해시 + 개별 솔트
- 토큰: JWT 기반 인증 토큰
- 세션: 안전한 세션 ID 생성 (UUID)
- 개인정보: 필요 시 AES-256 암호화
6.2 계정 보안 정책
- 계정 잠금: 5회 연속 실패 시 30분 잠금
- 세션 타임아웃: 30분 비활성 시 자동 만료
- 토큰 갱신: 리프레시 토큰을 통한 안전한 토큰 갱신
7. 캐시 전략
7.1 Redis 캐시 설계
Cache Key Pattern: auth:{category}:{identifier}
- auth:user:{user_id} -> 사용자 기본 정보 (TTL: 30분)
- auth:permissions:{user_id} -> 사용자 권한 목록 (TTL: 1시간)
- auth:session:{session_id} -> 세션 정보 (TTL: 세션 만료시간)
- auth:failed_attempts:{user_id} -> 실패 횟수 (TTL: 30분)
7.2 캐시 무효화 전략
- 권한 변경 시: 해당 사용자 권한 캐시 삭제
- 계정 잠금/해제 시: 사용자 정보 캐시 삭제
- 로그아웃 시: 세션 캐시 삭제
8. 데이터 관계도 요약
8.1 핵심 관계
auth_users(1) : (N)auth_user_sessionsauth_users(1) : (N)auth_user_permissionsauth_services(1) : (N)auth_permissionsauth_permissions(1) : (N)auth_user_permissionsauth_users(1) : (N)auth_login_historyauth_users(1) : (N)auth_permission_access_log
8.2 외부 서비스 연동
- 고객 정보: Bill-Inquiry 서비스의 고객 데이터를 캐시로만 참조
- 회선 정보: Product-Change 서비스의 회선 데이터를 캐시로만 참조
- 서비스 메타데이터: 각 서비스의 메뉴/기능 정보를 캐시로 관리
9. 성능 고려사항
9.1 예상 데이터 볼륨
- 사용자 수: 10만 명 (초기), 100만 명 (목표)
- 일일 로그인: 10만 회
- 세션 동시 접속: 1만 개
- 로그 보관 기간: 1년 (압축 보관)
9.2 성능 최적화
- 커넥션 풀: 20개 커넥션 (초기)
- 읽기 전용 복제본: 조회 성능 향상
- 파티셔닝: 로그 테이블 월별 파티셔닝
- 아카이빙: 1년 이상 로그 별도 보관
10. 관련 문서
- ERD 다이어그램: auth-erd.puml
- 스키마 스크립트: auth-schema.psql
- 유저스토리: ../../userstory.md
- API 설계서: ../api/auth-service-api.yaml