BE / 인프라: Next.js API, MySQL + Redis (세션 / 캐싱 / 동시성 제어), Naver OAuth + 세션 기반 인증
기술 목표
세션 기반 인증 설계로 클라이언트–서버 간 인증 흐름 구현 (httpOnly 쿠키 + 단일 디바이스 로그인 + OAuth 2.0 연동)
Redis + MySQL 패턴을 활용한 실시간 동시성 제어 (룰렛 동시 참여 제한, Rate Limiting, 쿨다운 관리)
봇 / 부정행위 방지 시스템 구축 (이메일 도메인 화이트리스트, 가입 / 삭제 패턴 탐지, IP 기반 자동 블랙리스트)
Lighthouse 전 항목 95점 이상 달성을 목표로 웹 성능 최적화 (이미지 변환, 정적 파일 압축, 번들 최적화, CLS 방지 등)
AI 툴(Claude Code) 활용으로 개발 생산성 극대화 시도 — 보일러플레이트, 리팩토링 등 개발 과정에 AI 페어 프로그래밍 적용
프로젝트 아키텍처
Next.js로 프론트엔드와 백엔드를 단일 프로젝트에서 관리하며 엔드포인트를 직접 구현했습니다.
세션 기반 인증을 채택해 DB 유저 테이블과 클라이언트 측 httpOnly 쿠키에 세션 토큰을 저장하고, 단일 디바이스 로그인을 강제했습니다.
Redis + MySQL 이중 저장소 패턴으로, 실시간 동시성 제어(룰렛, Rate Limiting)는 Redis가, 영구 데이터 저장 및 감사 로그는 MySQL이 담당합니다.
Vercel로 Production 환경에 배포하고, 라즈베리파이 홈서버에 운영 측과 진행 단계를 공유하는 개발 웹페이지를 따로 제작해 배포 환경을 분리했습니다.
주요 기능
메인 랜딩 페이지: 이벤트 참여자가 첫 접속 시 보는 화면으로, 축제의 개략적인 정보와 미디어, CTA(축제 사전 신청 등) 버튼이 배치돼 있습니다.
사전 참가 신청 페이지: 다중 폼으로 구성돼 있으며, 회원가입 시 입력한 정보로 개인정보를 채우고 참여 유형·인원·특이 사항 등을 입력합니다. 이미 참여한 인원은 이 페이지에서 사전 참가증 페이지를 보게 됩니다.
온라인 축제 페이지: 퀴즈, 응원 댓글, 가족 글쓰기, 랜덤 이벤트 탭으로 구성돼 있습니다. 참여 기록을 바탕으로 상품을 제공하며, 랜덤 이벤트는 하루에 한 번으로 제한했습니다.
응원 댓글 탭: 로그인한 사용자가 200자 이내의 응원 메시지를 작성할 수 있으며, 30초 작성 제한으로 도배를 방지합니다. 댓글 목록은 최신순·인기순 정렬과 무한 스크롤을 지원하고, 좋아요 버튼을 누르면 화면에 즉시 반영된 뒤 서버와 동기화해 데이터 일관성을 유지합니다.
고민했던 점들
보안 문제 — 계정 악용
DB 화이트리스트에 등록된 이메일 도메인만 가입을 허용해 일회용 이메일을 차단하고, 전화번호·이메일을 SHA256으로 해싱해 블랙리스트와 대조합니다. 같은 IP에서 24시간 내 10회 이상 가입 시도 시 차단하며, 계정 탈퇴 후 12시간 재가입 대기 기간을 두어 반복 생성·삭제를 방지합니다. 가입 시마다 패턴을 기록해 삭제 횟수·계정 유지 시간 기준으로 위험도를 분류하고 관리자가 관리할 수 있도록 했습니다.
세션 보안
서버 DB에 세션 토큰을 저장해 관리하며, 다른 기기에서 로그인 시 기존 세션을 자동 만료시켜 동시 접속을 차단합니다. 세션이 무효화된 상태로 보호된 페이지에 접근하면 "다른 기기에서 로그인하여 현재 세션이 종료되었습니다" 메시지와 함께 로그인 페이지로 이동합니다. 또한 인증 실패 시 발생할 수 있는 무한 리다이렉트를 쿠키 기반으로 감지해, 5초 내 3회 이상 반복되면 강제 로그아웃 처리합니다.
성과
약 400명이 참여한 행사를 Redis 기반 동시성 제어로 무중단 운영
회고
AI 페어 프로그래밍을 처음 도입한 프로젝트였습니다. 일정이 빠듯했던 탓도 있지만, 디자인 시안이 전달되지 않은 페이지를 급하게 AI로 채우다 보니 'AI가 만든 티가 나는' 화면이 그대로 들어갔고, 완성도 면에서 스스로도 아쉬움이 남았습니다.
대신 이 경험을 계기로 디자인을 따로 공부하기 시작했고, 이후 프로젝트부터는 AI 특유의 결과물을 지양하도록 프롬프트를 더 구체적으로 다듬거나 화면을 직접 설계하는 방식으로 접근하고 있습니다.