전체 글

개 발 자 로 살 아 남 기
· TIL
JWT vs 세션, 그리고 JWK의 정체TL;DR"JWT가 죽은 게 아니라, JWT를 브라우저 세션 관리 도구로 쓰던 오용이 교정된 것."다시 상기하자, 쿠키 vs JWT는 대립 축이 아님, 쿠키는 전송 수단, JWT는 토큰 포맷.발단better-auth, Supabase Auth 등 최근 인증 솔루션들이 JWT(JWK)를 지원하면서도기본값은 쿠키+세션인 걸 보고 의문이 생겼다. 분명 몇 년 전엔 "JWT로 통일" 분위기였는데?1. 인증 트렌드는 실제로 한 바퀴 돌았다JWT 전성기 (~2015–2021)SPA + REST API 분리 아키텍처의 유행과 정확히 겹친다.프론트와 백이 다른 도메인, "stateless라 스케일링에 좋다"는 마케팅,튜토리얼마다 복붙되던 localStorage 저장 패턴.실무에서..
· TIL
"로그인 성공과 동시에 차단 알림이?"어드민에 로그인할 때마다 슬랙으로 "IP 차단" 알림이 왔습니다.사유: 표적: 로그인 표면 (/api/auth/callback/google)IP: 223.62.16.68 (SK Telecom)이상한 점: 알림은 차단됐다는데 내 로그인은 멀쩡히 성공했습니다.타이밍도 정확히 내가 로그인한 순간이었고요.오탐인가? 버그인가? 싶어서 파봤는데, 결론은... 크롬 확장 Wappalyzer가 내가 방문한 OAuth 콜백 URL(일회용 인가 코드 포함)을 통째로 수집해서, 주거용 프록시 망에서 재접속하고 있었습니다.알림은 오탐이 아니라 이 유출 트래픽을 잡아낸 진짜 신호였습니다.조사 과정1) 알림 ≠ 내 로그인 요청코드상 슬랙 알림은 403 차단과 같은 분기에서만 발송됩니다.즉 알..
· TIL
멀티플레이어 미니 FPS 만들기 2편(운영편)전체 흐름코드 정리(상수 중앙화) → 멀티룸(로비) → EC2 배포 → 맵 권위화 → 자연 지형 → 아레나 확장 → 밤하늘 → rubber-banding 진단 진행 방식이 기본편과 달랐다. 기본편 보러가기기본편 단계에서는 한 단계씩 내가 직접 검증하며 구현했고,여기는 클로드코드로 에이전트 파이프라인(architect → implementer → reviewer → qa)으로 굵직한 작업 단위를 처리했다.Part 1 - 상수/매직넘버 중앙화무엇 / 왜서버 전반에 흩어진 매직넘버를 단일 소스로 모았다. 핵심은 숨은 결합을 드러내는 것.예를 들어 틱 레이트 TICK_HZ=30과 물리 timestep=1/30은 반드시 같아야 하는데 따로 떨어져 있었다.스폰 높이 0...
· TIL
멀티플레이어 미니 FPS 만들기 1편(기본편)어두운 아레나에서 손전등으로 앞을 비추며 페인트볼로 눈싸움하는, 최대 3인용 웹 FPS를 0에서 끝까지 만든 기록.과정을 잊지 않고자 기록하는, 남이 읽기엔 불친절한 기록물.결과물배포: https://eunoh.top/tests/mini-fps백엔드: 권위 게임 서버 (Node + ws, Rapier 물리, 30Hz 틱)프론트: 클라이언트 (Next 16 / React 19 / three.js · R3F · drei)어떤 게임인가컨셉: 총기 난사가 아니라 눈싸움/페인트볼. 페인트볼이 포물선을 그리며 날아가고, 회피가 가능하다.분위기: 거의 검정에 가까운 아레나. 각 플레이어는 손전등을 들고 앞을 비춘다. 어둠 속에서 다른 사람의 손전등 불빛이 휘청거리며 움직이..
· TIL
Vercel → AWS 마이그레이션 마스터 플랜Next.js 앱을 Vercel에서 AWS(ECS Fargate)로 옮기는 작업을,처음부터 끝까지 어떻게 설계하고 진행했는지의 압축 기록.다음에 같은 일을 할 때 코드 디테일이 아니라 순서·결정·함정 중심으로 펼쳐보기 위한 노트.1. 무엇을, 왜Next.js Vercel 배포시, RDS 와 직접 붙어야 할 경우 any-open을 피할 수 없다.RDS any-open 하지 않으려면 돈내고 Vercel static ip를 쓰거나 aws 이전이 필요하다.대상: Next.js 16 앱 (App Router, RSC, Better Auth, Prisma 7)출발: Vercel (Edge + Vercel Build, 환경변수 UI 입력)도착: AWS ECS Fargat..
· TIL
비개발 팀에게 RDS 조회 환경을 안전하게 전달하기1. 배경HQ 마케터와 기획자가 내부 데이터를 직접 확인해야 하는 상황이 있었다.다만 이들은 SQL이나 개발 환경에 익숙하지 않았고, RDS를 직접 노출하거나 관리자 계정을 공유하는 방식은 보안상 적절하지 않았다.그래서 다음 조건을 만족하는 방식을 구성했다.RDS는 외부에 직접 공개하지 않는다.Bastion EC2를 통해서만 접근한다.HQ 전용 DB 계정은 SELECT 권한만 가진다.비개발자는 복잡한 SSH 명령어를 직접 입력하지 않는다.Windows 환경에서도 실행 가능해야 한다.Claude Desktop의 MCP Postgres 서버에서 사용할 수 있어야 한다.2. 최종 아키텍처HQ Windows PC ↓ PowerShell SSH Tunnelloc..
· TIL
Nemotron Personas — 임베딩 기반 페르소나 검색 시스템 구현 회고한 줄 요약NVIDIA Nemotron 한국어 페르소나 데이터셋 100만 건을 OpenAI 임베딩으로 벡터화하고,pgvector + HNSW로 의미 검색 시스템을 구축한 뒤,NestJS API + Next.js 프론트로 광고 도메인 페르소나 검색기를 만든 프로젝트.만든 것배포: https://personas.eunoh.top (API), https://eunoh.top/tests/personas (UI)관측성: https://grafana.eunoh.top (Cloudflare Zero Trust로 보호)최종 스택[Next.js 프론트] ↓ [NestJS API (홈 우분투 서버)] ↓ ├─→ [OpenAI text-embed..
· TIL
관측성 처음 세팅해본 회고0. 시작 vs 끝 시점의 멘탈 모델시작 시점의 멘탈 모델"관측성 = 슬랙으로 알림 받는 것""알림 받으면 로그는 어디서 보지...?"→ 알림은 단편적이고 컨텍스트가 없었음. 서버 SSH 들어가서 journalctl, docker logs 뒤지는 게 일과.메트릭/로그/트레이스의 차이를 모름. 그냥 "로그"가 전부였음.OTel이라는 단어는 들어봤지만 "텔레메트리가 대체 어디로 어떻게 가는지" 감이 없었음.끝 시점의 멘탈 모델관측성은 "증상을 보고 → 원인을 파고들 수 있는 환경"이다.증상: request rate, error rate, latency p95/p99 같은 메트릭원인: 그 시점 로그, 그 요청의 trace알림은 "심각도와 맥락을 담아" 받는 것. 단순 에러 발생이 아니..
· TIL
pgvector + HNSW 검색 시스템 설계 후기0. 시작 vs 끝 시점의 멘탈 모델시작 시점의 멘탈 모델pg_trgm + GIN 같은 거 해봤으니 pgvector도 비슷하게 인덱스 만들고 WHERE + ORDER BY 하면 될 거 같다끝 시점의 멘탈 모델HNSW는 일반 인덱스와 본질이 다르다. "사전 그래프"여서 필터와 결합되는 순간 옵티마이저의 path 선택 문제가 발생.옵티마이저는 데이터 분포 보고 케이스별로 옳은 선택을 하고 있다 (Path A vs Path B).우리가 할 일은 ef_search 같은 힌트로 후보 풀 크기를 조절하는 것.100만건 적재는 INSERT가 아니라 COPY. 라운드트립 vs 단일 스트림 차이.1. 호스팅 결정: Supabase / Railway / 로컬 Docker후..
0. 벡터 임베딩 처음 구현해본 후기1. 임베딩의 본질 — "특정 모델만의 좌표계"시작 시점의 멘탈 모델"어깨너머로 본 벡터 임베딩. 1536차원이라는데 대체 그게 무슨 차원이라는 거지?"끝 시점의 멘탈 모델인간이 1536차원 배열을 보고 의미를 읽을 수는 없다.대신 "두 벡터의 거리가 얼마나 가까운가"가 의미적 유사도를 표현한다.더 중요한 깨달음: 임베딩은 "절대적 의미 좌표계"가 아니라 특정 모델만의 좌표계다.text-embedding-3-small의 좌표 ≠ BGE-M3의 좌표두 벡터를 비교하려면 같은 모델로 만들어야만 한다.→ 인덱싱한 모델과 검색 시 쓰는 모델이 반드시 같아야 한다!차원 수(1536, 3072 등)는 "표현 해상도". 높을수록 미세한 의미 차이를 담을 수 있지만, 저장·연산 비용..
adminisme
elseif