- CSRF: CookieCsrfTokenRepository(이중제출 토큰) + SPA용 CsrfTokenRequestAttributeHandler,
CsrfCookieFilter로 XSRF-TOKEN 쿠키 강제 렌더. /api/auth/login·/api/public/** 는 예외.
프론트 api.ts가 변경요청에 X-XSRF-TOKEN 헤더 자동 주입.
- 세션쿠키 SameSite=Lax·HttpOnly, prod는 Secure=${ACS_COOKIE_SECURE:false}(HTTPS 시 활성).
- h2-console permitAll·frameOptions.sameOrigin을 spring.h2.console.enabled에 연동 → prod 자동 비노출.
- CORS allowed-origins를 acs.cors.allowed-origins 프로퍼티로 외부화(prod 기본 빈 값, nginx 동일출처).
- .env.example·docker-compose에 ACS_CORS_ALLOWED_ORIGINS·ACS_COOKIE_SECURE 추가.
검증: 빌드/테스트 통과, curl로 CSRF 차단(403)·토큰 통과(404)·로그인/공개 예외·dev h2-console 확인.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
77 lines
1.9 KiB
YAML
77 lines
1.9 KiB
YAML
services:
|
|
db:
|
|
image: postgres:15
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
volumes:
|
|
- db_data:/var/lib/postgresql/data
|
|
networks:
|
|
- acs-net
|
|
|
|
app:
|
|
build:
|
|
context: ../backend
|
|
dockerfile: Dockerfile
|
|
image: acs-app:local
|
|
restart: unless-stopped
|
|
environment:
|
|
SPRING_PROFILES_ACTIVE: prod
|
|
POSTGRES_HOST: db
|
|
POSTGRES_PORT: 5432
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
# Pass delivery (dev = log only; hanbank = real LMS via DMZ API)
|
|
ACS_SMS_PROVIDER: ${ACS_SMS_PROVIDER:-dev}
|
|
ACS_SMS_API_URL: ${ACS_SMS_API_URL:-http://210.104.132.59:8000}
|
|
ACS_PUBLIC_BASE_URL: ${ACS_PUBLIC_BASE_URL:-http://localhost}
|
|
# Security: CORS origins (empty = same-origin via nginx); cookie Secure (enable under HTTPS)
|
|
ACS_CORS_ALLOWED_ORIGINS: ${ACS_CORS_ALLOWED_ORIGINS:-}
|
|
ACS_COOKIE_SECURE: ${ACS_COOKIE_SECURE:-false}
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- acs-net
|
|
|
|
web:
|
|
build:
|
|
context: ../frontend
|
|
dockerfile: Dockerfile
|
|
image: acs-web:local
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${WEB_PORT:-80}:80"
|
|
depends_on:
|
|
- app
|
|
networks:
|
|
- acs-net
|
|
|
|
# One-shot user seeder (run manually): docker compose run --rm seed
|
|
seed:
|
|
image: python:3.12-slim
|
|
profiles: ["tools"]
|
|
working_dir: /work
|
|
volumes:
|
|
- ..:/work:rw
|
|
environment:
|
|
PGHOST: db
|
|
PGPORT: 5432
|
|
PGUSER: ${POSTGRES_USER}
|
|
PGPASSWORD: ${POSTGRES_PASSWORD}
|
|
PGDATABASE: ${POSTGRES_DB}
|
|
entrypoint: ["/bin/sh", "-c"]
|
|
command: ["pip install -q -r scripts/requirements.txt && python scripts/seed-load.py --file scripts/seeds/users.csv"]
|
|
depends_on:
|
|
- db
|
|
networks:
|
|
- acs-net
|
|
|
|
volumes:
|
|
db_data:
|
|
|
|
networks:
|
|
acs-net:
|