일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Kotlin 클래스
- Kotlin If
- django virtualenv
- Python
- github
- Variable declaration
- 파이썬 제어문
- python Django
- 파이썬 장고
- 클래스 속성
- 파이썬 반복문
- 장고 가상환경
- activate 오류
- Kotlin 클래스 속성정의
- Kotlin else if
- 파이썬 클래스
- 다중조건문
- 넥스트js
- git
- Python Class
- Kotlin Class
- 희망
- 자바 기본타입
- Kotlin 조건문
- 좋은글
- 성공
- 파이썬
- 도전
- NextJs
- 강제 타입변환
- Today
- Total
키모스토리
#4. register (MongoDB, Jose, session, cookie) 본문
#4. register (MongoDB, Jose, session, cookie)
키모형 2025. 4. 4. 17:52MongoDB: The World’s Leading Modern Database
Get your ideas to market faster with a flexible, AI-ready database. MongoDB makes working with data easy.
www.mongodb.com
1. 인스톨
npm install mongodb
2. connecton string setup
mongodb+srv://user_id:<db_password>@cluster0.y42buoh.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
root / .env.local 파일 작성
// db-id, db-password : 몽고디비에 설정된 실재 id, pwd 입력
DB_URI = "mongodb+srv://[db-id]:[db-password]@cluster0.y42buoh.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"
/src/lib/db.js 작성 (몽고디비 연결 및 db작업 정의)
// lib/db.js
const { MongoClient, ServerApiVersion } = require("mongodb");
// 환경설정 파일 (.env.local) 에서 DB_URI를 가져옵니다.
if(!process.env.DB_URI) {
throw new Error("DB_URI is not set");
}
// MongoDB 클라이언트를 생성합니다.
const client = new MongoClient(process.env.DB_URI, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
},
});
// DB에 연결하는 함수입니다.
async function getDB(dbName) {
try {
// Connect the client to the server
await client.connect();
console.log(">>>> Connected to MongoDB <<<<");
return client.db(dbName);
} catch (err) {
console.error(err);
}
}
// DB에 연결된 후, collection을 가져오는 함수입니다.
// DBNAME은 next_blog_db 입니다.
export async function getCollection(collectionName) {
const db = await getDB('next_blog_db');
if(db) {
// console.log(db.collection(collectionName));
return db.collection(collectionName);
}
return null;
}
Password Hash
npm i bcrypt
문자열을 bcrypt를 이용하여 해시값으로 변경
// Hash the password before saving it to the database.
// 비밀번호를 해시하여 DB에 저장합니다.
const hashedPassword = await bcrypt.hash(password, 10);
// users collection에 회원가입 정보를 저장합니다.
// mongodb collection에 신규 정보 등록 (비번은 해시값으로)
const result= await userCollection.insertOne({
name,
email,
password: hashedPassword,
});
Session, Cookie 정보를 JWT로 생성, 이용
Jose
npm i jose
Secretkey 생성 방법
1. OpenSSL 설치
Windows에 OpenSSL을 설치하는 방법:
- https://slproweb.com/products/Win32OpenSSL.html 에서 최신 버전의 Win64 OpenSSL 설치 파일을 다운로드하여 설치하세요.
- 보통 Win64 OpenSSL vX.X.X (Light 버전으로도 충분함) 선택
설치할 때 “The OpenSSL binaries/libraries will be copied to the Windows system directory” 옵션을 체크 해제하고, 사용자 디렉토리에 설치하세요.
2. 환경 변수 등록
설치 후 OpenSSL의 설치 경로(예: C:\Program Files\OpenSSL-Win64\bin)를 시스템 환경 변수 PATH에 추가해야 합니다.
방법:
- Win 키 + 검색 → "환경 변수" 입력 → 시스템 환경 변수 편집 클릭
- "환경 변수(N)..." 버튼 클릭
- "시스템 변수"에서 Path 선택 후 편집
- OpenSSL의 bin 폴더 경로 추가 예: C:\Program Files\OpenSSL-Win64\bin
- 확인 → 확인 → PowerShell 새로 열기
3. 테스트
PowerShell을 다시 열고 아래 명령을 입력해 확인:
버전 정보가 출력되면 성공입니다.
그 다음 아래 명령 실행 가능:
openssl rand -base64 32
회원가입 처리
src/actions/auth.js
"use server";
import bcrypt from "bcrypt";
import { getCollection } from "@/lib/db";
import { RegisterFormSchema } from "@/lib/rules";
import { redirect } from "next/navigation";
import { createSession } from "@/lib/session";
export async function register(state, formData) {
// await new Promise((resolve) => setTimeout(resolve, 3000));
// 회원가입 요청으로 넘어온 formData를 사용하여 유효성 검사를 수행합니다.
// 유효성 검사 규칙은 src/lib/rules.js에 정의되어 있습니다.
const validatedFields = RegisterFormSchema.safeParse({
name: formData.get("name"),
email: formData.get("email"),
password: formData.get("password"),
confirmPassword: formData.get("confirmPassword"),
});
// 유효성 검사에 실패한 경우, 에러 메시지를 반환합니다.
// 에러 메시지는 src/lib/rules.js에 정의된 규칙에 따라 다르게 표시됩니다.
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
name: formData.get("name"),
email: formData.get("email"),
};
}
// 유효성 검사 통과 후 DB에 회원가입 정보를 저장합니다.
const {name, email, password} = validatedFields.data;
// console.log(name, email, password);
// next_blog_db DB에서 users collection(테이블)을 가져옵니다.
const userCollection = await getCollection("users");
// users collection이 존재하지 않는 경우, 에러 메시지를 반환합니다.
if( !userCollection) {
return {
errors: validatedFields.error.flatten().fieldErrors,
name: formData.get("name"),
email: formData.get("email"),
};
}
// user email이 이미 존재하는 경우, 에러 메시지를 반환합니다.
const exitingUser = await userCollection.findOne({ email });
if (exitingUser) {
return {
errors: { email: "Email already exists." },
name: formData.get("name"),
};
}
// Hash the password before saving it to the database.
// 비밀번호를 해시하여 DB에 저장합니다.
const hashedPassword = await bcrypt.hash(password, 10);
// users collection에 회원가입 정보를 저장합니다.
const result= await userCollection.insertOne({
name,
email,
password: hashedPassword,
});
// console.log(result.insertedId);
// Create Session
await createSession(result.insertedId.toString());
// Rediect to login page after successful registration.
redirect("/dashboard");
}
회원가입이 정상 처리된 후 세션생성 단계 진행 => /lib/session.js 에 세션관련 코드 정의 (jose, jwt, cookie)
// Create Session
await createSession(result.insertedId.toString());
/lib/session.js
import { cookies } from "next/headers";
import { jwtVerify, SignJWT } from "jose";
// 환경설정 파일에서 SESSION_SECRET을 가져옵니다.
const secretKey = process.env.SESSION_SECRET;
const encodeKey = new TextEncoder().encode(secretKey);
// 세션을 암호화하는 함수입니다.
// payload는 세션에 저장할 데이터입니다.
// 이 함수는 JWT를 생성하여 세션을 암호화합니다.
// JWT는 JSON Web Token의 약자로, JSON 객체를 사용하여 정보를 안전하게 전송하는 방법입니다.
export async function encrypt(payload){
return new SignJWT(payload)
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("6h")
.sign(encodeKey);
};
// 세션을 복호화하는 함수입니다.
// session은 암호화된 세션 데이터입니다.
export async function decrypt(session) {
try {
const { payload } = await jwtVerify(session, encodeKey, {
algorithms: ["HS256"],
});
return payload;
} catch (error) {
console.error("Failed to vrefy session", error);
}
}
// 세션을 생성하는 함수입니다.
// userId는 세션에 저장할 사용자 ID입니다.
export async function createSession(userId) {
const expireAt = new Date(Date.now() + 6 * 60 * 60 * 1000); // 6시간 후 만료
const session = await encrypt({ userId, expireAt });
const cookieStore = await cookies();
cookieStore.set("session", session, {
httpOnly: true,
secure: true,
expires: expireAt,
sameSite: "lax",
path: "/",
});
}
가입 완료, dashboard 로 이동 완료, application -> cookies 정보에 쿠키값 확인
'Web Devlopment > Next-Blog Project' 카테고리의 다른 글
#6. Active Links (0) | 2025.04.05 |
---|---|
#5. server-only (0) | 2025.04.05 |
#3. zod.dev (validation) (0) | 2025.04.04 |
#2. useActionState (0) | 2025.04.04 |
#1. Setup (0) | 2025.04.03 |