jwt 작동되도록 수정..

This commit is contained in:
김인섭 2025-06-25 21:17:17 +09:00
parent e0ed7c598b
commit bdf43e1906
6 changed files with 30 additions and 3260 deletions

3235
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@types/bcryptjs": "^2.4.6",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^22",
"drizzle-kit": "^0.30.2",
@ -28,9 +29,9 @@
"vite-plugin-devtools-json": "^0.2.0"
},
"dependencies": {
"@node-rs/argon2": "^2.0.2",
"@oslojs/crypto": "^1.0.1",
"@oslojs/encoding": "^1.1.0",
"bcryptjs": "^3.0.2",
"drizzle-orm": "^0.40.0",
"jsonwebtoken": "^9.0.2",
"postgres": "^3.4.5"

View File

@ -8,10 +8,10 @@ const handleAuth: Handle = async ({ event, resolve }) => {
const accessToken = event.cookies.get(auth.jwtCookieName);
if (accessToken) {
const { user, isValid } = auth.validateJwtToken(accessToken);
const { userId, isValid } = auth.validateJwtToken(accessToken);
if (isValid && user) {
event.locals.user = user;
if (isValid && userId) {
event.locals.user = {id: userId};
return resolve(event);
}
// 액세스 토큰이 유효하지 않으면 refresh 시도
@ -37,8 +37,8 @@ const handleAuth: Handle = async ({ event, resolve }) => {
}
// 유효한 리프레시 토큰이 있으면 사용자 정보 조회
const user = await db.query.users.findFirst({
where: (users, { eq }) => eq(users.id, userId)
const user = await db.query.refreshTokens.findFirst({
where: (refreshTokens, { eq }) => eq(refreshTokens.id, userId)
});
if (!user) {
@ -48,13 +48,12 @@ const handleAuth: Handle = async ({ event, resolve }) => {
}
// 새 액세스 토큰 발급
const newAccessToken = auth.generateAccessToken(user.id, user.email);
const newAccessToken = auth.generateAccessToken(user.id);
auth.setAccessTokenCookie(event, newAccessToken);
// 사용자 정보 설정
event.locals.user = {
id: user.id,
email: user.email
};
return resolve(event);

View File

@ -27,6 +27,16 @@ export function generateRefreshToken(userId: string) {
);
}
// 일반 토큰 검증
export function validateJwtToken(token: string) {
try {
const decoded = jwt.verify(token, JWT_SECRET) as { userId: string };
return { userId: decoded.userId, isValid: true };
} catch (error) {
return { userId: null, isValid: false };
}
}
// 리프레시 토큰 검증
export function validateRefreshToken(token: string) {
try {

View File

@ -13,5 +13,5 @@ export const refreshTokens = pgTable('refresh_tokens', {
createdAt: timestamp('created_at').defaultNow().notNull()
});
export type RefreshTokens = typeof refreshTokens.$inferSelect;
export type User = typeof user.$inferSelect;

View File

@ -1,4 +1,7 @@
import { hash, verify } from '@node-rs/argon2';
// D:/gitea/Jwt/src/routes/demo/lucia/login/+page.server.ts
// 1. @node-rs/argon2 대신 bcryptjs를 임포트합니다.
import { hash, compare } from 'bcryptjs';
import { encodeBase32LowerCase } from '@oslojs/encoding';
import { fail, redirect } from '@sveltejs/kit';
import { eq } from 'drizzle-orm';
@ -37,12 +40,8 @@ export const actions: Actions = {
return fail(400, { message: 'Incorrect username or password' });
}
const validPassword = await verify(existingUser.passwordHash, password, {
memoryCost: 19456,
timeCost: 2,
outputLen: 32,
parallelism: 1,
});
// 2. verify를 compare 함수로 변경하고, 인자 순서를 (평문, 해시)로 맞춥니다.
const validPassword = await compare(password, existingUser.passwordHash);
if (!validPassword) {
return fail(400, { message: 'Incorrect username or password' });
}
@ -62,7 +61,6 @@ export const actions: Actions = {
const email = formData.get('email');
const password = formData.get('password');
const userId = generateUserId();
// 타입 체크 및 검증
if (!email || typeof email !== 'string') {
@ -72,13 +70,10 @@ export const actions: Actions = {
if (!password || typeof password !== 'string') {
return fail(400, { message: '비밀번호가 필요합니다' });
}
const passwordHash = await hash(password, {
// recommended minimum parameters
memoryCost: 19456,
timeCost: 2,
outputLen: 32,
parallelism: 1,
});
// 3. hash 함수에 salt rounds 값을 인자로 전달합니다. (보통 10~12를 사용)
const saltRounds = 10;
const passwordHash = await hash(password, saltRounds);
try {
await db.insert(table.user).values({ id: userId, email, passwordHash });