From 9764a96918ab057b7e14c323257f268a878f56f6 Mon Sep 17 00:00:00 2001 From: Jaybe Date: Mon, 9 Jun 2025 23:15:42 +0900 Subject: [PATCH] =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/controllers/authController.js | 40 ++++++++++------ backend/models/User.js | 10 +++- frontend/src/services/authService.js | 2 +- frontend/src/views/auth/Login.vue | 67 ++++++++++++++++----------- 4 files changed, 75 insertions(+), 44 deletions(-) diff --git a/backend/controllers/authController.js b/backend/controllers/authController.js index cb6fb00..6717931 100644 --- a/backend/controllers/authController.js +++ b/backend/controllers/authController.js @@ -10,26 +10,26 @@ require('dotenv').config(); // 로그인 exports.login = async (req, res) => { try { - const { email, password } = req.body; + const { username, password } = req.body; - // 이메일 필수 확인 - if (!email) { - return res.status(400).json({ message: '이메일은 필수 항목입니다.' }); + // 사용자명 필수 확인 + if (!username) { + return res.status(400).json({ message: '사용자명은 필수 항목입니다.' }); } // 사용자 조회 - const user = await User.findOne({ where: { email } }); + const user = await User.findOne({ where: { username } }); // 사용자가 존재하지 않는 경우 if (!user) { - return res.status(401).json({ message: '이메일 또는 비밀번호가 올바르지 않습니다.' }); + return res.status(401).json({ message: '사용자명 또는 비밀번호가 올바르지 않습니다.' }); } // 비밀번호 검증 const isPasswordValid = await user.validatePassword(password); if (!isPasswordValid) { - return res.status(401).json({ message: '이메일 또는 비밀번호가 올바르지 않습니다.' }); + return res.status(401).json({ message: '사용자명 또는 비밀번호가 올바르지 않습니다.' }); } // 마지막 로그인 시간 업데이트 @@ -39,6 +39,7 @@ exports.login = async (req, res) => { const token = jwt.sign( { id: user.id, + username: user.username, email: user.email, role: user.role, name: user.name @@ -70,6 +71,7 @@ exports.login = async (req, res) => { const userData = { id: user.id, name: user.name, + username: user.username, email: user.email, role: user.role, status: user.status, @@ -90,26 +92,33 @@ exports.login = async (req, res) => { // 회원가입 exports.register = async (req, res) => { try { - const { name, email, password, role, status } = req.body; + const { name, email, username, password, role, status } = req.body; // 필수 필드 검증 - if (!name || !email || !password) { - return res.status(400).json({ message: '이름, 이메일, 비밀번호는 필수 항목입니다.' }); + if (!name || !email || !username || !password) { + return res.status(400).json({ message: '이름, 이메일, 사용자명, 비밀번호는 필수 항목입니다.' }); } // 이메일 중복 확인 - const existingUser = await User.findOne({ where: { email } }); + const existingEmail = await User.findOne({ where: { email } }); - if (existingUser) { + if (existingEmail) { return res.status(400).json({ message: '이미 등록된 이메일입니다.' }); } + + // 사용자명 중복 확인 + const existingUsername = await User.findOne({ where: { username } }); + + if (existingUsername) { + return res.status(400).json({ message: '이미 사용 중인 사용자명입니다.' }); + } // 사용자 생성 const newUser = await User.create({ name, email, + username, password, - username: email, role: role || 'user', status: status || 'active' }); @@ -118,6 +127,7 @@ exports.register = async (req, res) => { const userResponse = { id: newUser.id, name: newUser.name, + username: newUser.username, email: newUser.email, role: newUser.role, status: newUser.status, @@ -197,8 +207,8 @@ exports.updateProfile = async (req, res) => { // 프로필 업데이트 const updateData = { name: name || user.name, - email: email || user.email, - username: email || user.email // username도 이메일과 동일하게 업데이트 + email: email || user.email + // username은 변경하지 않음 - 로그인 식별자로 사용되기 때문 }; // 비밀번호가 제공된 경우에만 업데이트 diff --git a/backend/models/User.js b/backend/models/User.js index e4f04fb..1efa958 100644 --- a/backend/models/User.js +++ b/backend/models/User.js @@ -1,6 +1,7 @@ const { DataTypes } = require('sequelize'); const { sequelize } = require('../config/database'); const bcrypt = require('bcrypt'); +const { encrypt, decrypt } = require('../utils/encryption'); const User = sequelize.define('User', { id: { @@ -32,7 +33,14 @@ const User = sequelize.define('User', { validate: { isEmail: true }, - comment: '이메일' + comment: '이메일 (암호화됨)', + get() { + const rawValue = this.getDataValue('email'); + return rawValue ? decrypt(rawValue) : null; + }, + set(value) { + this.setDataValue('email', value ? encrypt(value) : null); + } }, role: { type: DataTypes.ENUM('admin', 'clubadmin', 'user'), diff --git a/frontend/src/services/authService.js b/frontend/src/services/authService.js index 776276a..07218d9 100644 --- a/frontend/src/services/authService.js +++ b/frontend/src/services/authService.js @@ -6,7 +6,7 @@ import apiClient from './api'; const authService = { /** * 로그인 - * @param {Object} credentials - 로그인 정보 (이메일, 비밀번호) + * @param {Object} credentials - 로그인 정보 (사용자명, 비밀번호) * @returns {Promise} - 로그인 결과 */ login(credentials) { diff --git a/frontend/src/views/auth/Login.vue b/frontend/src/views/auth/Login.vue index 9459f5f..1483733 100644 --- a/frontend/src/views/auth/Login.vue +++ b/frontend/src/views/auth/Login.vue @@ -4,9 +4,9 @@

볼링 클럽 매니저 로그인

- - - {{ emailError }} + + + {{ usernameError }}
@@ -29,6 +29,12 @@

회원가입

+ +
+ + + {{ registerUsernameError }} +
@@ -58,10 +64,7 @@ class="w-full" /> {{ registerPasswordConfirmError }}
-
- - -
+