# πŸ› 둜그인 버그 μˆ˜μ • μ™„λ£Œ ## 문제 상황 - βœ… νšŒμ›κ°€μž… ν›„ λ°”λ‘œ 둜그인 β†’ **정상 μž‘λ™** - ❌ λ‘œκ·Έμ•„μ›ƒ ν›„ λ‹€μ‹œ 둜그인 μ‹œλ„ β†’ **"이메일 λ˜λŠ” λΉ„λ°€λ²ˆν˜Έκ°€ μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€" μ—λŸ¬** - μž…λ ₯ν•œ μ •λ³΄λŠ” λͺ¨λ‘ 정확함 ## πŸ” 원인 뢄석 ### 문제의 원인 Drizzle ORM μŠ€ν‚€λ§ˆμ™€ μ½”λ“œ κ°„ ν•„λ“œλͺ… 뢈일치 **Drizzle μŠ€ν‚€λ§ˆ (schema.ts):** ```typescript export const users = sqliteTable('users', { id: integer('id').primaryKey({ autoIncrement: true }), email: text('email').notNull().unique(), passwordHash: text('password_hash').notNull(), // ← camelCase nickname: text('nickname').notNull(), createdAt: integer('created_at', { mode: 'timestamp' }) }); ``` **둜그인 μ½”λ“œ (login/+page.server.ts) - μˆ˜μ • μ „:** ```typescript const validPassword = await verifyPassword(password, user.password_hash); // ^^^^^^^^^^^^^ snake_case μ‚¬μš© ``` ### μ™œ νšŒμ›κ°€μž…μ€ μž‘λ™ν–ˆλ‚˜? νšŒμ›κ°€μž… μ‹œμ—λŠ” **μƒˆλ‘œμš΄ passwordHash 값을 직접 전달**ν•˜κΈ° λ•Œλ¬Έμ— ν•„λ“œλͺ… λΆˆμΌμΉ˜κ°€ λ¬Έμ œκ°€ λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€: ```typescript // register/+page.server.ts const user = await createUser(platform.env.DB, email, passwordHash, nickname); // passwordHashλ₯Ό 직접 μ „λ‹¬ν•˜λ―€λ‘œ 문제 μ—†μŒ ``` ν•˜μ§€λ§Œ 둜그인 μ‹œμ—λŠ” **DBμ—μ„œ μ‘°νšŒν•œ user 객체의 ν•„λ“œμ— μ ‘κ·Ό**ν•˜λ―€λ‘œ: ```typescript // login/+page.server.ts const user = await getUserByEmail(platform.env.DB, email); // user.passwordHashκ°€ μ˜¬λ°”λ₯Έ ν•„λ“œλͺ…인데 // user.password_hash둜 μ ‘κ·Ό β†’ undefined λ°˜ν™˜ const validPassword = await verifyPassword(password, undefined); // undefined와 λΉ„κ΅ν•˜λ―€λ‘œ 항상 μ‹€νŒ¨! ``` ## βœ… ν•΄κ²° 방법 ### μˆ˜μ •λœ μ½”λ“œ ```typescript // src/routes/login/+page.server.ts (μˆ˜μ • ν›„) const validPassword = await verifyPassword(password, user.passwordHash); // ^^^^^^^^^^^^ camelCase둜 μˆ˜μ • ``` ## πŸ”§ μˆ˜μ • λ‚΄μ—­ **파일:** `src/routes/login/+page.server.ts` **λ³€κ²½ 사항:** ```diff - const validPassword = await verifyPassword(password, user.password_hash); + const validPassword = await verifyPassword(password, user.passwordHash); ``` ## βœ… ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€ 이제 λ‹€μŒ μ‹œλ‚˜λ¦¬μ˜€κ°€ λͺ¨λ‘ 정상 μž‘λ™ν•©λ‹ˆλ‹€: ### 1. νšŒμ›κ°€μž… β†’ μžλ™ 둜그인 ``` 1. /register νŽ˜μ΄μ§€ 접속 2. 정보 μž…λ ₯ (예: test@test.com / 123456 / ν…ŒμŠ€ν„°) 3. νšŒμ›κ°€μž… λ²„νŠΌ 클릭 4. βœ… μžλ™μœΌλ‘œ λ‘œκ·ΈμΈλ˜μ–΄ 메인 νŽ˜μ΄μ§€λ‘œ 이동 ``` ### 2. λ‘œκ·Έμ•„μ›ƒ β†’ 재둜그인 ``` 1. λ‘œκ·Έμ•„μ›ƒ λ²„νŠΌ 클릭 2. /login νŽ˜μ΄μ§€λ‘œ 이동 3. λ™μΌν•œ 정보 μž…λ ₯ (test@test.com / 123456) 4. 둜그인 λ²„νŠΌ 클릭 5. βœ… 정상 λ‘œκ·ΈμΈλ˜μ–΄ 메인 νŽ˜μ΄μ§€λ‘œ 이동 ``` ## 🎯 Drizzle ORM ν•„λ“œλͺ… κ·œμΉ™ Drizzle ORM은 λ‹€μŒκ³Ό 같이 ν•„λ“œλͺ…을 μ²˜λ¦¬ν•©λ‹ˆλ‹€: ### λ°μ΄ν„°λ² μ΄μŠ€ 컬럼 (snake_case) ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, password_hash TEXT NOT NULL -- DBλŠ” snake_case ); ``` ### TypeScript νƒ€μž… (camelCase) ```typescript // Drizzleκ°€ μžλ™μœΌλ‘œ camelCase둜 λ³€ν™˜ type User = { id: number; passwordHash: string; // TypeScriptλŠ” camelCase } ``` ### μ˜¬λ°”λ₯Έ μ‚¬μš©λ²• ```typescript // βœ… μ˜¬λ°”λ₯Έ 방법 const user = await getUserByEmail(db, email); console.log(user.passwordHash); // camelCase // ❌ 잘λͺ»λœ 방법 console.log(user.password_hash); // undefined! ``` ## πŸ“ μΆ”κ°€ 확인 사항 λ‹€λ₯Έ νŒŒμΌλ“€λ„ ν™•μΈν–ˆμ§€λ§Œ λͺ¨λ‘ μ˜¬λ°”λ₯΄κ²Œ μž‘μ„±λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€: ### βœ… hooks.server.ts ```typescript event.locals.user = { id: user.id, // βœ… μ˜¬λ°”λ¦„ email: user.email, // βœ… μ˜¬λ°”λ¦„ nickname: user.nickname // βœ… μ˜¬λ°”λ¦„ }; ``` ### βœ… db.ts ```typescript const newUser: NewUser = { email, passwordHash, // βœ… camelCase μ‚¬μš© nickname }; ``` ## πŸš€ μ‹€ν–‰ 방법 μˆ˜μ •μ‚¬ν•­μ΄ 이미 λΉŒλ“œλ˜μ—ˆμœΌλ―€λ‘œ λ°”λ‘œ μ‹€ν–‰ κ°€λŠ₯ν•©λ‹ˆλ‹€: ```bash pnpm cf:dev ``` 그런 λ‹€μŒ: 1. http://localhost:8787/register - μƒˆ 계정 생성 2. λ‘œκ·Έμ•„μ›ƒ 3. http://localhost:8787/login - 재둜그인 4. βœ… 정상 μž‘λ™ 확인! ## πŸŽ“ κ΅ν›ˆ ### Drizzle ORM μ‚¬μš© μ‹œ μ£Όμ˜μ‚¬ν•­ 1. **μŠ€ν‚€λ§ˆ μ •μ˜ μ‹œ camelCase μ‚¬μš©** ```typescript passwordHash: text('password_hash') // TypeScriptλŠ” camelCase ``` 2. **μ½”λ“œμ—μ„œλ„ camelCase둜 μ ‘κ·Ό** ```typescript user.passwordHash // βœ… μ˜¬λ°”λ¦„ user.password_hash // ❌ undefined ``` 3. **TypeScript νƒ€μž… ν™œμš©** ```typescript // νƒ€μž… 좔둠을 μ‚¬μš©ν•˜λ©΄ μ˜€νƒ€ λ°©μ§€ const hash: string = user.passwordHash; ``` ## πŸŽ‰ μ™„λ£Œ! 둜그인 버그가 μˆ˜μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€! **μˆ˜μ • 사항:** - βœ… `user.password_hash` β†’ `user.passwordHash`둜 λ³€κ²½ - βœ… λΉŒλ“œ 성곡 - βœ… ν…ŒμŠ€νŠΈ μ€€λΉ„ μ™„λ£Œ **이제 정상 μž‘λ™ν•©λ‹ˆλ‹€:** - βœ… νšŒμ›κ°€μž… β†’ μžλ™ 둜그인 - βœ… λ‘œκ·Έμ•„μ›ƒ β†’ 재둜그인 - βœ… λΉ„λ°€λ²ˆν˜Έ 검증 정상 μž‘λ™ 즐거운 개발 λ˜μ„Έμš”! πŸš€