티스토리 뷰
SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계
12단계 — bcrypt로 비밀번호 해싱 + 세션 만료/연장 제대로 만들기
11단계에서 우리는 인증을 DB 기반 세션 구조로 바꿨습니다.
쿠키 → session_id
session_id → DB Session 조회
Session → User 조회
User → locals.user
이제 남은 문제 하나가 있습니다.
⚠️ 지금 비밀번호가 평문입니다.
즉 DB가 털리면 모든 계정이 바로 노출됩니다.
그래서 이번 단계에서 두 가지를 해결합니다.
1️⃣ 비밀번호를 bcrypt 해싱
2️⃣ 세션 만료 정책 + 자동 연장(sliding session)
이 두 개만 제대로 해도
인증 시스템이 서비스 수준으로 올라갑니다.
12단계 목표
- bcrypt로 비밀번호 저장
- 로그인 시 bcrypt 비교
- 세션 만료시간 관리
- 세션 자동 연장(sliding session)
- hooks에서 만료 세션 처리
1️⃣ bcrypt 설치
먼저 라이브러리 설치합니다.
npm install bcrypt
npm install -D @types/bcrypt
2️⃣ 비밀번호 해싱 유틸 만들기
비밀번호 관련 로직은 한 곳에 모으는 게 좋습니다.
src/lib/server/password.ts
import bcrypt from 'bcrypt';
const SALT_ROUNDS = 10;
export async function hashPassword(password: string) {
return bcrypt.hash(password, SALT_ROUNDS);
}
export async function verifyPassword(
password: string,
hash: string
) {
return bcrypt.compare(password, hash);
}
3️⃣ 기존 유저 비밀번호 해싱으로 변경
이제 seed 데이터를 바꿉니다.
prisma/seed.ts
import { PrismaClient, Role } from '@prisma/client';
import { hashPassword } from '../src/lib/server/password';
const prisma = new PrismaClient();
async function main() {
const adminPassword = await hashPassword('1234');
const userPassword = await hashPassword('1234');
await prisma.user.upsert({
where: { username: 'admin' },
update: {
password: adminPassword,
role: Role.ADMIN
},
create: {
username: 'admin',
password: adminPassword,
role: Role.ADMIN
}
});
await prisma.user.upsert({
where: { username: 'user' },
update: {
password: userPassword,
role: Role.USER
},
create: {
username: 'user',
password: userPassword,
role: Role.USER
}
});
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());
다시 실행:
npx prisma db seed
이제 DB 비밀번호는 이런 형태입니다.
$2b$10$XGsdjfsd.......
👉 평문이 아닙니다.
4️⃣ 로그인 로직 bcrypt 비교로 변경
src/routes/login/+page.server.ts
기존 코드에서 이 부분을 수정합니다.
❌ 이전
if (!user || user.password !== password)
✅ 변경
import { verifyPassword } from '$lib/server/password';
전체 핵심 부분:
const user = await prisma.user.findUnique({
where: { username }
});
if (!user) {
return fail(400, { error: '아이디 또는 비밀번호가 틀렸습니다.' });
}
const valid = await verifyPassword(
password,
user.password
);
if (!valid) {
return fail(400, { error: '아이디 또는 비밀번호가 틀렸습니다.' });
}
이제 비밀번호 비교는
bcrypt.compare()
로 수행됩니다.
5️⃣ 세션 만료 정책 설정
지금 세션 만료는 단순히 7일입니다.
하지만 서비스에서는 보통 두 가지 정책을 씁니다.
방식설명
| fixed session | 로그인 후 일정 시간 |
| sliding session | 활동할 때마다 연장 |
보통 sliding session을 사용합니다.
6️⃣ 세션 자동 연장 구현
session.repo.ts에 함수 추가합니다.
export async function refreshSession(sessionId: string) {
const expiresAt = getSessionExpiry();
await prisma.session.update({
where: { id: sessionId },
data: { expiresAt }
});
return expiresAt;
}
7️⃣ hooks에서 세션 자동 연장
src/hooks.server.ts
import {
findValidSession,
refreshSession
} from '$lib/server/session.repo';
핵심 수정:
const session = await findValidSession(sessionId);
if (!session) {
event.cookies.delete('session_id', { path: '/' });
event.locals.user = null;
return resolve(event);
}
// 활동 시 세션 연장
await refreshSession(sessionId);
event.locals.user = {
id: String(session.user.id),
role: session.user.role
};
이제 사용자가 활동할 때마다
expiresAt → 다시 7일 연장
됩니다.
8️⃣ 세션 만료 처리
만약 세션이 만료되면
expiresAt < now
findValidSession에서 걸러집니다.
그래서 hooks에서
cookies.delete('session_id')
로 자동 로그아웃 처리됩니다.
9️⃣ 보안 옵션 추가 (중요)
쿠키 옵션을 이렇게 바꾸는 게 좋습니다.
cookies.set('session_id', session.id, {
path: '/',
httpOnly: true,
sameSite: 'lax',
secure: process.env.NODE_ENV === 'production'
});
옵션의미
| httpOnly | JS 접근 차단 |
| sameSite | CSRF 방지 |
| secure | HTTPS만 |
🔥 여기까지 오면 인증 시스템 수준
지금 구조는 이미 꽤 괜찮습니다.
bcrypt password
DB session
session expiry
session refresh
role
hooks auth
server guard
이건 웬만한 서비스 인증 구조입니다.
오늘 단계 핵심 한 문장
비밀번호는 저장하는 게 아니라 “해싱해서 보관”한다.
그리고
세션은 “시간 제한이 있는 신분증”이다.
SvelteKit, bcrypt, 인증시스템, 세션관리, SSR인증, Prisma, MySQL, 주니어개발자, 백엔드기초, 풀스택
'study > 백엔드' 카테고리의 다른 글
| 백엔드 프로젝트는 어떻게 시작해야 할까? FastAPI · Spring Boot · Node.js로 뼈대부터 잡는 첫 글 (0) | 2026.03.19 |
|---|---|
| SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계 (0) | 2026.03.10 |
| SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계 (0) | 2026.03.02 |
| SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계 (0) | 2026.02.25 |
| SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계 (0) | 2026.02.09 |
- Total
- Today
- Yesterday
- llm
- Prisma
- rag
- flax
- JAX
- seo 최적화 10개
- SEO최적화
- Express
- Next.js
- node.js
- Docker
- REACT
- DevOps
- 웹개발
- kotlin
- ai철학
- NestJS
- 쿠버네티스
- fastapi
- 압박면접
- nextJS
- Python
- PostgreSQL
- 딥러닝
- CI/CD
- JWT
- LangChain
- 개발블로그
- Redis
- 백엔드개발
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
