| User 모델 스키마 정의
데이터 스키마를 정의하고 DB와 연결된 구조를 제공한다.
backend/models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
}, { timestamps: true });
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
userSchema.methods.matchPassword = async function(enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
module.exports = mongoose.model('User', userSchema);
/ userSchema : User 스키마를 정의한다.
* unique: true -- 중복 방지를 위한 조건.
* timestamps: true -- createdAt, updatedAt 자동 생성
/ userSchema.pre : 미리 저장 전 비밀번호 암호화
사용자가 비밀번호를 입력할 때마다 자동으로 bcrypt로 해시 처리한다.
기존 비밀번호가 변경되지 않았다면 다시 해시하지 않고 넘어간다.
/ userSchema.methods.matchPassword : 비밀번호 비교 메서드
로그인 시 입력된 비밀번호(enteredPassword)와 해시된 비밀번호를 비교한다.
/ mongoose.model : User라는 이름으로 MongoDB에 user 컬렉션으로 저장된다.
| 회원가입, 로그인 로직을 처리하기 위한 컨트롤러
실제 동작을 처리한다. 요청(req)데이터를 받고 모델을 이용해 DB와 통신한 후 응답(res)을 반환한다.
backend/controllers/authControllers.js
const User = require('../models/User');
const generateToken = require('../utils/generateToken');
// 회원가입 컨트롤러
exports.registerUser = async (req, res) => {
const { username, email, password } = req.body;
try {
// 이미 존재하는 사용자 체크
const userExists = await User.findOne({ email });
if (userExists) return res.status(400).json({ message: '이미 존재하는 이메일입니다.' });
const user = await User.create({ username, email, password });
res.status(201).json({
_id: user._id,
username: user.username,
email: user.email,
token: generateToken(user._id),
});
} catch (error) {
res.status(500).json({ message: '회원가입 오류', error: error.message });
}
};
// 로그인 컨트롤러
exports.loginUser = async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user || !(await user.matchPassword(password))) {
return res.status(401).json({ message: '이메일 또는 비밀번호가 올바르지 않습니다.' });
}
res.json({
_id: user._id,
username: user.username,
email: user.email,
token: generateToken(user._id),
});
} catch (error) {
res.status(500).json({ message: '로그인 오류', error: error.message });
}
};
DB와 JWT관련 기능을 사용하기 위해 불러와주고
/ registerUser : 회원가입 컨트롤러
클라이언트가 보내온 username, email, password를 req.body에서 꺼낸다.
try문에서는 같은 이메일을 가진 유저가 DB에 있는지 체크하고 User.create로 새 유저를 생성한다.
이때 비밀번호는 User모델에서 bcrypt를 통해 해싱된다.
그다음 res.status로 유저 정보를 응답으로 보내고 JWT 토큰도 함께 반환한다.
/ loginUser : 로그인 컨트롤러
DB에서 이메일로 유저를 찾고 비밀번호 일치 여부를 matchPassword로 확인한다.
성공하면 토큰을 포함한 유저 정보를 반환하고 실패시 401에러를 반환한다.
| 라우터 연결
URL과 컨트롤러 함수를 연결한다. 예를들어 POST /api/auth/register 요청이 오면 registerUser 함수를 실행한다.
backend/routes/authRoutes.js
const express = require('express');
const { registerUser, loginUser } = require('../controllers/authController');
const router = express.Router();
router.post('/register', registerUser);
router.post('/login', loginUser);
module.exports = router;
express.Router()로 라우터 객체를 생성하고 authController.js에서 정의한 registerUser, loginUser함수를 불러온다.
/api/auth/regiser 경로로 POST 요청이 오면 registerUser함수가 실행된다.
module.exports - router; 외부에서 사용이 가능하게 내보낸다.
이렇게 해서 server.js에서 등록한 라우트와 연결된다.
| JWT Token 모듈 작성
빠진것이 있다. 지금까지 순서대로 작성했다면 아마도 터미널에 에러가 떴을 것이다.

Error: Cannot find module '../utils/generateToken' ...
어떤 문제인지 대략 눈치 챌 수 있다. 컨트롤러에서 generateToken을 사용하려는데 아직 그 파일을 만들지 않았다.
backend/utils/generateToken.js
const jwt = require('jsonwebtoken');
const generateToken = (userId) => {
return jwt.sign({ id: userId }, process.env.JWT_SECRET, {
expiresIn: '7d',
});
};
module.exports = generateToken;
또한, .env 파일에서 JWT_SECRET이 지정되어 있는지 확인하고 설정해주어야 한다.
| 테스트
아직 클라이언트 개발을 하지 않았기 때문에 Thunder Client로 요청과 응답을 테스트 한다.
Response에 결과 값이 아래와 같은 형식으로 나온다면 성공이다.
/ register

/ login
회원 가입시 입력했던 이메일과 비밀번호를 정확히 입력해야 한다.

'STUDY > Project' 카테고리의 다른 글
| 게시판 로직 - Post, postController, postRoutes (0) | 2025.04.30 |
|---|---|
| NodeJS, MongoDB, react 회원가입, 로그인, 게시판 구현 플로우 (0) | 2025.04.30 |
| MongoDB연결 파일 작성 및 서버 실행하기 (0) | 2025.04.29 |
| 서버 시작 파일 및 환경변수 파일 작성 - server.js, .env, nodemon설정 (0) | 2025.04.29 |
| nodejs react 프로젝트 기본 구조 구성 및 설치 (0) | 2025.04.28 |