| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- next/script
- 웹 디자인
- npm module
- useState
- next auth
- openapi-generator
- useSWRImmutable
- window.scrollY
- NEXT
- typescript-axios
- refreshaccesstokenerror
- .vscode
- nextauth
- python
- flutter
- typescript
- es module
- refetchInterval
- openapitools.json
- auth.js
- npm publish
- Tanstack Query
- openapi-generator-cli
- 폰트 최적화
- svgr/cli
- next.js
- refresh token race condition
- trustHost
- React
- npm library
- Today
- Total
목록전체 글 (46)
김재욱의 이모저모
2025년 11월, 국회의원 표결 내역 프로젝트를 하다가 정말 미칠 것 같았던 하루를 보냈다.안건 상세 페이지에 들어가면 300명의 의원 표결 정보를 보여줘야 하는데, 초기 로딩이 너무 느려서 사용자가 답답해할 것 같았다. 그래서 Infinite Scroll을 구현하기로 했다. "쉽겠지~" 했는데...1차 시도: 순진한 생각처음엔 간단하게 생각했다.사용자 진입 → 50명씩 API 호출 → 스크롤하면 다음 50명 호출열린국회정보 API는 pIndex, pSize 파라미터를 지원하니까 당연히 될 줄 알았다.// 이렇게 하면 되겠지?const apiData = await fetchVoteRecords({ billId: bill.billId, pIndex: page, // 페이지 번호 pSize:..
문제 발견성능 개선 좀 해볼까 하고 Lighthouse 돌렸는데 충격적인 걸 발견했다뭐가 문제냐면:HTML + CSS + JS: 약 1MB폰트 하나: 3MB 🤯font 로딩하느라 2.8초나 걸리다니 오마이갓실제 사용자가 겪는 문제사용자: 사이트 접속화면: 빈 화면 또는 깨진 텍스트(2-3초 대기...)화면: 텍스트 뿅! (폰트 로드됨, 레이아웃 깨짐)화면: 이미지 하나씩 느리게 뜸...사용자: "아 느려, 뒤로가기 ㅂㅂ"모바일에서는 더 심각했어:3G 환경: 폰트 로딩 15초 😱원인 분석폰트 문제1. TTF 포맷 사용// layout.tsxconst pretendard = localFont({ src: './fonts/PretendardVariable.ttf', // 3MB TTF display:..
문제 발생동화책 뷰어를 만들면서 페이지 전환을 매끄럽게 하고 싶었어.당연히 다음 페이지 이미지를 미리 로드(preload)해야겠다고 생각했지.useEffect(() => { // 다음 4개 페이지 이미지를 미리 불러오기 const preloadNextImages = (startIndex: number) => { const pagesToPreload = bookData.pages.slice(startIndex, startIndex + 4); pagesToPreload.forEach((page) => { if (page.imageUrl) { const img = new Image(); img.src = page.imageUrl; // 미리 로드! }..
문제 발견이전 글에서 Refresh Token 만료 시 자동 로그아웃을 구현했다.잘 동작하는 것 같았는데, 가끔씩 이상한 로그가 찍혔다.✅ refreshed token is success✅ refreshed token is success✅ GET /api/auth/session 200 in 25473ms // 25초??✅ GET /api/auth/session 200 in 3005ms❌ RefreshAccessTokenError: 유효하지 않은 토큰입니다.refreshToken error - invalidating session뭐지?Refresh가 성공했다가 갑자기 실패함로그인된 상태에서 갑자기 로그아웃됨새로고침하면 다시 정상이게 뭔 일이야?원인 분석의심 1: 여러 요청이 동시에 Refresh를 시도하..
문제 발견블로그에 카카오 애드핏 광고를 달았다. PC용 배너(728x90)랑 모바일용 배너(320x50)를 각각 만들어서 반응형으로 보여주려고 했다.근데 이상한 일이 벌어졌다:PC 화면으로 페이지 로드 → PC 광고 잘 뜸 ✅개발자 도구로 모바일 화면 전환 → 광고 안 뜸 ❌새로고침하면 → 그제서야 모바일 광고 뜸 ✅뭐지? 왜 화면 크기 바꾸면 안 되는 거지?초기 구현 (잘못된 방법)1단계: layout.tsx에서 전역 스크립트 로드// layout.tsxexport default async function RootLayout({ children }) { return ( {children} );}공식 문서대로 했다. lazyOnload로 ..
상황동화책 생성 기능이 있다. 사용자가 책을 만들면 백엔드에서 AI가 열심히 이미지 생성하고 TTS 만들고 한다.이게 시간이 좀 걸린다. 그래서 책 상태가 3가지다:PROCESSING: 만드는 중COMPLETED: 완성FAILED: 실패요구사항:PROCESSING 상태의 책이 있으면 10초마다 자동으로 상태 확인하고 싶다.근데 전부 COMPLETED면 굳이 계속 API 호출할 필요 없다.첫 번째 시도: useMemo + refetchIntervalconst hasProcessingBooks = useMemo(() => { return data?.pages.some((page) => page.books.some((book) => book.status === BookStatus.PROCESSING) ..
문제 상황사용자가 로그인 후 오랜 시간 동안 창을 닫아뒀다가 돌아오면 이상한 일이 일어났다.화면상으론 로그인되어 있는 것처럼 보임근데 모든 API 호출이 실패함콘솔에는 RefreshAccessTokenError 찍힘사용자는 뭐가 문제인지 모름로그아웃 버튼도 떠있고, 세션도 살아있는 것처럼 보이는데 뭐가 문제일까?왜 이런 일이 생겼나1. Session maxAge vs Refresh Token 만료 시간 차이// auth.tssession: { strategy: 'jwt', maxAge: 60 * 60 * 24, // 24시간}NextAuth 설정에서 session은 24시간 동안 유효하다고 설정했다.근데 백엔드의 refresh token은 이보다 짧게 만료될 수 있다.시나리오:사용자가 로그인 (오전 ..
문제 발견로컬에서는 잘 되던 로그아웃이 Vercel에 배포하고 나니까 안 되더라구요. 로그아웃 버튼을 눌렀는데 로그인 페이지로 이동은 하는데, 뭔가 이상한 거예요. 세션은 삭제된 것 같은데 헤더를 보면 여전히 "로그아웃" 버튼이 있더라고여.처음엔 "어? 배포 환경에서만 안 되네?" 했는데, 알고 보니 NextAuth v5의 프로덕션 배포에서 흔히 나오는 문제였어요.증상 정리먼저 정확히 뭐가 문제였는지 정리해볼게요:로컬 환경: 로그아웃 버튼 클릭 → 세션 삭제 → 로그인 페이지 이동 → 헤더에 "로그인" 버튼 표시 ✅프로덕션 환경: 로그아웃 버튼 클릭 → /auth/login으로 이동은 함 → 근데 헤더에 "로그아웃" 버튼이 그대로 있음 ❌더 신기한 건, middleware는 제대로 작동한다는 거였어요. ..
문제 발견Next.js + NextAuth로 인증을 구현하던 중, Header 컴포넌트에서 로그인/로그아웃 버튼이 깜빡이는 현상이 발생했어요. 특히 로그인 후 페이지 이동 시, 잠깐 동안 "로그인" 버튼이 보였다가 "로그아웃" 버튼으로 바뀌는 불편한 UX를 보여줬죠.문제점 분석1. Server-Client 하이드레이션 불일치 (Hydration Mismatch)기존 구조는 이랬어요:// layout.tsx (Server Component)export default async function RootLayout({ children }) { const session = await auth(); // 서버에서 세션 가져옴 return ( {/* Client Component */} ..
문제 상황NextAuth.js를 사용하여 JWT 기반 인증을 구현하던 중, 토큰 갱신 과정에서 이상한 현상이 발생했습니다.첫 번째 세션 호출은 성공적으로 refreshAccessToken을 실행하여 토큰을 갱신그러나 동시에 발생한 나머지 세션 호출들은 모두 실패콘솔 로그를 확인해보니 여러 개의 세션이 거의 동시에 호출되고 있었음원인 분석Race Condition 발생문제의 핵심은 여러 세션 호출이 동시에 발생했을 때였습니다.async jwt({ token, user }) { // 토큰 만료 확인 if (Date.now() 시나리오:페이지가 로드되면서 여러 컴포넌트에서 auth() or useSession()를 동시에 호출모든 호출이 거의 동시에 토큰 만료를 확인모든 호출이 동시에 refreshAcce..