분류 전체보기 41

[프로젝트] Spring Boot 에서 인증 시스템 설계하기 - OTP 2FA + JWT + Redis로 보안 구현 (feat. 스프링부트, Spring Security, Redis TTL 기반 임시 저장소)

상담사용 인증 시스템을 설계하며 고민한 보안 아키텍처, Redis 기반 OTP 챌린지, JWT Refresh Token Rotation 전략을 3단계 Phase로 정리했습니다. 1. [Phase 1] 로그인 → OTP 챌린지 생성설계 원칙: "비밀번호만으로는 문을 열 수 없다" 상담사가 이메일과 비밀번호를 제출하면, 서버는 토큰을 발급하지 않습니다.대신 OTP 챌린지를 생성하고 이메일로 6자리 인증 코드를 발송합니다. 이 단계에서 신경 쓴 보안 포인트는 세 가지입니다. 첫째, 이메일 열거(Email Enumeration) 방지.이메일이 존재하지 않는 경우와 비밀번호가 틀린 경우를 동일한 에러 코드(INVALID_CREDENTIALS)로 응답합니다. 공격자가 "이 이메일은 가입되어 있다"는 정보를 얻지 ..

프로젝트 2026.02.19

[프로젝트] 3.49s에서 0.925ms로: Google API 배치 호출과 PostGIS로 응답 시간 74% 개선 (feat. 스프링부트)

1. 왜 API를 전환했는가 - 12초짜리 API현재 개발 중인 프로젝트는 N명의 참여자가 모두 공평하게 이동할 수 있는 최적의 만남 장소를 찾는 서비스입니다.핵심 알고리즘1. 참여자 N명의 위치 → 무게중심(centerPoint) 계산2. 무게중심 5km 반경 내 지하철역 M개 검색3. 각 역까지 모든 참여자의 대중교통 경로 탐색4. MinSum(총 이동시간 최소) 기준 Top 3 추천 평가 지표minSum: 모든 참여자 이동시간의 합계 (가장 중요)minMax: 가장 먼 참여자의 이동시간 (공평성)avgDuration: 평균 이동시간초기 구현: ODsay API 선택 이유✅ 국내 대중교통 특화 (환승 정보 정확도 높음)✅ 무료 API (비용 부담 없음)❌ Rate Limit 엄격 (동시 요청 제한)❌..

프로젝트 2026.02.17

[데이터베이스] .NET Framework 1.1에서 Oracle 11g + 19c를 동시에 연결한 방법 (ORA-28040 해결기)

1. 문제 상황레거시 환경(.NET Framework 1.1, VS2003)에서두 개의 Oracle DB(11g, 19c)를 동시에 사용해야 했다. 사용 구조 System.Data.OracleClientOCI DLL 직접 로딩32bit IIS 환경19c 접속 시 다음 에러 발생ORA-28040: No matching authentication protocol 2. 단순한 해결책이 통하지 않았던 이유이전 글 참고https://hyunolike.tistory.com/25 [CS] 왜 .NET은 Oracle Client가 필요했고 Spring은 필요 없을까? (feat. 닷넷, 스프링, 스프링부트)“같은 Oracle DB를 쓰는데,왜 .NET에서는 항상 Oracle Client 설치 때문에 고생했고Sprin..

데이터베이스 2026.02.16

[프로젝트] "AWS가 이렇게 쉬웠어?" 네이버 클라우드 경험자가 말하는 AWS EC2 배포 자동화 구축기

이전 글에서 https://hyunolike.tistory.com/37 [프로젝트] 네이버 클라우드로 인프라 구축하기 (VPC, 서브넷, 로드밸런서)Spring Boot 애플리케이션을 개발하고 나면 이제 실제 사용자가 접속할 수 있는 프로덕션 환경을 구축해야 합니다.저는 Naver Cloud Platform을 선택했고 Docker와 GitHub Actions를 활용해 자동 배포 파이프라hyunolike.tistory.com네이버 클라우드로 인프라 구축기를 작성했습니다. 상담 관리 플랫폼을 개발하면서 AWS 클라우드 환경에서 배포 자동화를 구축했습니다.이 글에서는 AWS EC2 배포 자동화 과정과 함께 실제 프로덕션 환경에서 두 클라우드 플랫폼(네이버클라우드, AWS)을 사용하며 느낀 차이점을 공유합니다...

프로젝트 2026.02.16

[프로젝트] save() 없이도 저장된다? JPA Cascade + Dirty Checking으로 참여자 생성 API를 3단계 리팩토링한 이야기 (feat. 퍼사드 패턴, 스프링부트)

https://github.com/dnd-side-project/dnd-14th-8-backend GitHub - dnd-side-project/dnd-14th-8-backend: [모여락] 모임 일정 및 장소 조율 통합 서비스[모여락] 모임 일정 및 장소 조율 통합 서비스. Contribute to dnd-side-project/dnd-14th-8-backend development by creating an account on GitHub.github.com 서비스가 커질수록 “로직이 어디에 있는지” 찾는 시간이 늘어납니다.참여자 생성 API를 리팩토링하면서 아키텍처를 더 ‘깔끔하게’ 만들려는 시도에서 출발했지만최종적으로는 JPA가 제공하는 영속성 컨텍스트의 힘(Dirty Checking + Casc..

프로젝트 2026.02.08

[프로젝트] 네이버 클라우드로 인프라 구축하기 (VPC, 서브넷, 로드밸런서)

Spring Boot 애플리케이션을 개발하고 나면 이제 실제 사용자가 접속할 수 있는 프로덕션 환경을 구축해야 합니다.저는 Naver Cloud Platform을 선택했고 Docker와 GitHub Actions를 활용해 자동 배포 파이프라인까지 구성했습니다.이 글에서는 제가 겪은 시행착오와 해결 과정을 공유하려고 합니다. 1. 왜 Naver Cloud Platform을 선택했나?AWS나 GCP도 좋지만 한국 서비스를 위해서는 Naver Cloud Platform이 몇 가지 장점이 있었습니다.우선 국내 리전이라 레이턴시가 낮고 한글 문서가 잘 되어 있어서 트러블슈팅이 수월했습니다.무엇보다 학생 크레딧이나 스타트업 지원 프로그램을 활용하면 비용 부담도 적습니다. 2. 인프라 아키텍처 설계프로덕션 환경을 구..

프로젝트 2026.02.05

[프로젝트] N명의 최적 만남 장소 찾기: 지리 알고리즘 설계와 실시간 응답 개선 (feat. CompletableFuture, Semaphore)

1. 프로젝트 개요여러 명이 만남을 약속할 때 모두에게 공정한 최적의 만남 장소를 추천하는 API를 만들었습니다. 1.1. 핵심 로직참가자들의 위치를 받아 지리적 중심점 계산 (3D 좌표 변환)중심점 반경 5km 내 지하철역 5개 검색 (Kakao API)각 지하철역까지 모든 참가자의 대중교통 경로 탐색 (ODsay API)총 소요시간(MinSum) 기준으로 Top 3 추천 1.2. 사용 기술Spring Boot, RestTemplateKakao Local API (지하철역 검색)ODsay API (대중교통 경로 탐색)CompletableFuture (병렬 처리)Semaphore (동시 요청 제한) 2. 요청 프로세스 2.1. 요청 본문 { "participants": [ { "name": ..

프로젝트 2026.02.02

[CS] VPN은 되는데 DB는 안 된다? NAT, 보안솔루션, IP 기준으로 파헤친 실무 장애 회고 (feat. ipconfig, netstat -a)

업무 중 VPN 접속은 정상인데 DB 접근이 안 되는 상황을 경험했다.에러 메시지는 단순했다.“보안서버에 등록되지 않은 IP입니다.” 처음엔 VPN, DB 계정, 방화벽 중 어디가 문제인지 감이 오지 않았다.하지만 이 문제는 설정 하나의 누락이 아니라,기업 네트워크 접근 제어 구조를 이해하지 못하면 절대 해결할 수 없는 문제였다. 이 글에서는사용자 PC → VPN → NAT → DB 보안 솔루션 → DB로 이어지는 전체 흐름을 기준으로문제 원인과 해결 과정을 정리한다.1. VPN IP ≠ 서버가 보는 IPVPN에 접속하면 사용자는 VPN 전용 IP를 할당받는다.로컬에서는 다음과 같이 확인할 수 있다. ipconfig → VPN 어댑터 IPnetstat -a → 실제 통신에 사용 중인 로컬 IP여기서는 n..

[WEB] 모바일 환경의 한계를 인정하고 설계하다 (쿠키 기반 식별로 이벤트 중복을 제어한 경험)

1. 문제는 “기능”이 아니라 “환경”이었다이벤트 댓글의 좋아요 중복 방지 기능을 구현하면서 가장 먼저 마주한 문제는 기능 자체가 아니었다.문제는 모바일 환경이었다. 모바일(LTE/5G) 환경에서는 접속할 때마다 IP가 동적으로 변경된다.즉, 동일 사용자가 같은 기기에서 접근하더라도 서버 입장에서는 매 요청이 다른 사용자처럼 보이는 구조다. 118.235.xxx.xxx121.128.xxx.xxx... 이로 인해 단순 IP 기반 검증은 다음과 같은 한계를 가졌다. 동일 사용자임에도 중복 참여로 인식되지 않음모바일 환경에서 공정성 보장 불가정상 사용자까지 제한하는 오탐 발생2. “완벽한 차단”이 아니라 “현실적인 통제”가 필요했다처음부터 목표를 명확히 정리했다.이 시스템의 목적은 해커를 막는 보안 시스템 ..

WEB 2026.01.20

[CS] HTTPS가 안 되던 API를 살린 방법 - Nginx SSL Proxy로 Mixed Content 해결하기 (feat. 각 환경별 SSL 인증서 동작 방식 - IIS, Linux, SSL Proxy)

깃허브 레포지토리 바로가기: https://github.com/hyunolike/vanillajs-based-spa더보기 이번 글에서는 실제로 HTTPS가 안 되던 문제를 직접 해결한 경험을 바탕으로SSH, SSL, 인증서, 프록시 서버가 각각 어떤 역할을 하고 요청 한 번이 어떤 과정을 거쳐 안전해지는지를 정리했다. 1. 문제의 시작 "로컬에서는 되는데 배포하면 안 된다"프론트엔드는 GitHub Pages로 배포되어 있었고 API 서버는 단순한 HTTP 서버였다.하지만 결과는 명확했다. 브라우저 콘솔: Blocked Mixed Content이유: HTTPS 페이지에서 HTTP API 호출👉 브라우저는 “보안 수준이 낮아지는 요청”을 자동으로 차단한다. 2. “그럼 HTTPS로 바꾸면 되잖아?” 여기..