[2025 ์๋ฐ๊ธฐ] ๐ชด์์ง์ฌ๋ค - ์น์ฑ ๋ฐ๋ ค์๋ฌผ ๊ด๋ฆฌ ๋ฐ ์ง๋ฃ ์๋น์ค

๋จผ์ ์น์ฌ์ดํธ์ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด์!
๋ก๊ทธ์ธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ์ ์์ ์ฟ ํค์ ์ธ์
์ค ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ก๊ทธ์ธ์ ๊ตฌํํ ๊ฒ์ธ์ง ๊ณ ๋ฏผํ๋ค.
๐ช์ฟ ํค
์ฟ ํค๋ ํด๋ผ์ด์ธํธ ์ธก์์ ์ํ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ด๋ค. ์๋ฒ๋ ์ฌ์ฉ์์ ์น ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๋ฅผ ๋ณด๋ด๋ฉฐ ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ์์ ๋ณด๋ธ ์ฟ ํค๋ฅผ ์ ์ฅํ๊ณ ์ดํ ์์ฒญ๊ณผ ํจ๊ป ๋์ผํ ์๋ฒ๋ก ๋ค์ ์ ์กํ ์ ์๋ค. ์ฆ ๋์ ์ ๋ณด์ ๊ดํ ๋ชจ๋ ๊ฒ์ ๊ธฐ์ตํ๊ธฐ ์ํด์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ๋ ๊ฒ์ด๋ค.
์ธ์
์ธ์
์ ์ฟ ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ์ง๋ง, ์ ๋ณด๋ฅผ ์๋ฒ ์ธก์์ ๊ด๋ฆฌํ๋ค๋ ์ ์์ ์ฐจ์ด๊ฐ ์๋ค.
์๋ฒ๋ ํด๋ผ์ด์ธํธ์ Session ID๊ฐ์ ๋ถ์ฌํ๊ณ ์ ๋ณด๋ ์๋ฒ์ ์ ์ฅํ๋ค.
์ดํ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ๋ผ ์๋ฒ์์ Session ID๋ฅผ ์กฐํํ์ฌ ํด๋ผ์ด์ธํธ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉํ๋ค.
์ธ์ ์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ์!
์ธ์
์ย ๋น๋ฐ๋ฒํธ์ย ๊ฐ์ย ์ธ์ฆย ์ ๋ณด๋ฅผย ์ฟ ํค์ย ์ ์ฅํ์งย ์๊ณ ย ์๋ฒ์ย ์ ์ฅํ๋ค.ย ๋์ ย ์ฟ ํค์๋ย ์ฌ์ฉ์ย ์๋ณ์์ธย session-id๋ฅผย ์ ์ฅํฉ๋๋ค.ย ย ์ด์ฒ๋ผย ์ธ์
๋ย ์ฟ ํค๋ฅผย ์ด์ฉํ์ง๋งย ์ถ์ ย ๋ถ๊ฐ๋ฅํย session-id๋ฅผย ์ฃผ๊ณ ๋ฐ๊ธฐย ๋๋ฌธ์ย ๋ณด์์ย ์์ ํ๋ค.ย
๋ฐ๋ผ์ย ๋
ธ์ถ๋๋ฉดย ์ย ๋๋ย ์ค์ํย ์ฌ์ฉ์์ ์ ๋ณด๋ย ์ธ์
์ย ์ด์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค.
express-session ๋ฏธ๋ค์จ์ด
์ธ์
๊ด๋ฆฌ์ฉ ๋ฏธ๋ค์จ์ด์ด๋ค.
ํน์ ์ฌ์ฉ์๋ฅผ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด๋ ๋ ์ ์ฉํ๊ฒ ์ฐ์ธ๋ค.
์ธ์
์ ์ฌ์ฉ์๋ณ๋ก req.session ๊ฐ์ฒด ์์ ์ ์ง๋๋ค.
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // ๊ฐ๋ฐ ํ๊ฒฝ์์ HTTPS๊ฐ ์๋ ๊ฒฝ์ฐ
maxAge: 1000 * 60 * 60 // 1์๊ฐ ๋์ ์ธ์
์ ์ง
}
}));
๋จผ์ ์ธ์
์ ์ํธํํ๊ธฐ ์ํ secret_key๋ฅผ ๊ฐ์ ธ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์์ ์ธ์
๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ์ ์๋ฒ๋ ์ธ์
์ ๋ค์ ์ ์ฅํ์ง ์๋๋ก ์ค์ ํ์๋ค. ๋ํ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ถํ์ํ ๋น ์ธ์
์ฟ ํค๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด saveUninitialized๋ฅผ false๋ก ํด์, ์ค์ ์ธ์
๋ฐ์ดํฐ๊ฐ ์ค์ ๋๊ธฐ ์ ๊น์ง๋ ์ธ์
์ ์์ฑํ์ง ๋ชปํ๋๋ก ํ์๋ค.
secure๊ฐ์ด true์ผ ๊ฒฝ์ฐ์๋ HTTPS ์ฐ๊ฒฐ์์๋ง ์ฟ ํค๊ฐ ์ ์ก๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ๊ฐ๋ฐ ํ๊ฒฝ์์ HTTPS๋ฅผ ์ฌ์ฉํ์ง ์์ ์ ์๋ค๊ณ ์๊ฐํด์ ์ฟ ํค์ ์ค์ ๊ฐ์ผ๋ก secure๋ฅผ false๋ก ํ๋ค.
๊ฐ๋ฐ์ด ์๋ฃ๋ ํ์ ๋ฐฐํฌ ํ๊ฒฝ์์๋ secure๋ฅผ true๋ก ๋ณ๊ฒฝํ ์์ ์ด๋ค!!!!
app.post('/login', async (req, res) => {
const { ID, password } = req.body;
try {
const user = await fetchUser(ID);
if (!user) {
return res.json({ success: false, message: "์กด์ฌํ์ง ์๋ ์์ด๋์
๋๋ค." });
}
if (password !== user.password) {
return res.json({ success: false, message: "๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ์ต๋๋ค." });
}
// ์ธ์
์ ์ด์ฉํ์ฌ ๋ก๊ทธ์ธ ์ํ ์ ์ฅ
req.session.user = {
ID: user.ID,
nickname: user.nickname
};
// ์ถ์ ๊ธฐ๋ก
const attendanceRecorded = await recordAttendance(user.ID);
if (attendanceRecorded) {
console.log(`${user.ID}๋์ ์ถ์์ด ๊ธฐ๋ก๋์์ต๋๋ค.`);
} else {
console.log(`${user.ID}๋์ ์ด๋ฏธ ์ค๋ ์ถ์ํ์ต๋๋ค.`);
}
res.json({ success: true, message: "๋ก๊ทธ์ธ ์ฑ๊ณต" });
} catch (error) {
console.error('๋ก๊ทธ์ธ ์๋ฌ:', error);
res.status(500).json({ success: false, message: "๋ก๊ทธ์ธ ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค." });
}
});
fetchUser(ID)๋ ์ฌ์ฉ์ ID๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์์ด๋ค.
๋ง์ฝ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ user๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด return์ ์ด์ฉํด ๋ ์ด์ ์งํ๋์ง ๋ชปํ๋๋ก ํ๋ค.
๋ก๊ทธ์ธ์ ์ฑ๊ณตํ๋ฉด ์ธ์
์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ค.
req.session.user์ ์์ด๋์ ๋๋ค์์ ์ ์ฅํ๋ค.
๋ฐ๋ผ์ ์ดํ ์ฌ์ฉ์๊ฐ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๋ฉด ์ฌ์ฉ์๊ฐ ๋๊ตฌ์ธ์ง ์๋ณ ๊ฐ๋ฅํ๋ฉฐ ๋ก๊ทธ์ธ ์ํ๋ฅผ ์ ์งํ ์ ์๋ค!
์์ด๋ ์ฐพ๊ธฐ ์ฝ๋
app.post('/find-id', async (req, res) => {
const { email } = req.body;
try {
const user = await fetchUserByEmail(email);
if (!user) {
return res.json({ success: false, message: "๋ฑ๋ก๋ ์ด๋ฉ์ผ์ด ์์ต๋๋ค." });
}
res.json({ success: true, message: "์์ด๋๋ฅผ ์ฐพ์์ต๋๋ค.", ID: user.ID });
} catch (error) {
console.error('์์ด๋ ์ฐพ๊ธฐ ์๋ฌ:', error);
res.status(500).json({ success: false, message: "์์ด๋ ์ฐพ๊ธฐ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค." });
}
});
๋จผ์ ํด๋ผ์ด์ธํธ๊ฐ email์ ์๋ฒ๋ก ๋ณด๋ด๋ฉด req.body์์ ์ด๋ฉ์ผ ๊ฐ์ ์ถ์ถํ์ฌ ๋ณ์ email์ ์ ์ฅํ๋ค.
๊ทธ๋ฆฌ๊ณ fetchUserByEmail(email)์ ์ด์ฉํด ์ฌ์ฉ์์ ์ด๋ฉ์ผ์ ๊ฐ์ ธ์จ๋ค.
ํด๋น ์ด๋ฉ์ผ์ ๊ฐ์ง ์ฌ์ฉ์๊ฐ ์กด์ฌํ๋ฉด user.ID๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ฐํํ๋๋ก ํ๋ค.
์์ ์ฝ๋์ ๋น์ทํ๊ฒ ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค!!!
๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ์ฝ๋
app.post('/find-password', async (req, res) => {
const { ID, email } = req.body;
try {
const user = await fetchUserByIdAndEmail(ID, email);
if (!user) {
return res.json({ success: false, message: "์์ด๋ ๋๋ ์ด๋ฉ์ผ์ด ์ผ์นํ์ง ์์ต๋๋ค." });
}
// ์ ๋น๋ฐ๋ฒํธ ์์ฑ ๋ฐ ์ ์ฅ
const newPassword = generateRandomPassword();
const hashedPassword = await hashPassword(newPassword);
await updateUserPassword(ID, hashedPassword);
// ์ด๋ฉ์ผ๋ก ์ ๋น๋ฐ๋ฒํธ ๋ฐ์ก
await sendEmail(email, "๋น๋ฐ๋ฒํธ ์ฌ์ค์ ", `์ ๋น๋ฐ๋ฒํธ: ${newPassword}`);
res.json({ success: true, message: "์ ๋น๋ฐ๋ฒํธ๊ฐ ์ด๋ฉ์ผ๋ก ๋ฐ์ก๋์์ต๋๋ค." });
} catch (error) {
console.error('๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ์๋ฌ:', error);
res.status(500).json({ success: false, message: "๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค." });
}
});
์ ๋น๋ฐ๋ฒํธ ์์ฑ ๋ฐ ์ํธํ
generateRandomPassword()๋ ์๋ก์ด ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ฑํ๋ ํจ์์ด๋ค.
hashPassword(newPassword)๋ ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํํ๋ ๋น๋๊ธฐ ํจ์์ด๋ค.
์ด ์ํธํ๋ ๊ฐ์ธ hashedPassword๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋๋ค.
await updateUserPassword(ID, hashedPassword);
๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํด๋น ID๋ฅผ ๊ฐ์ง ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ก ๋ง๋ ์ํธํ๋ ๋น๋ฐ๋ฒํธ๋ก ์
๋ฐ์ดํธ ํ๋ค.
ํ์๊ฐ์ ์ฝ๋
ID๊ฐ ์กด์ฌํ์ง ์๋ ์ ๊ท ๊ฐ์
์๋ค์ ์ํ ํ์๊ฐ์
๊ธฐ๋ฅ์ ๊ตฌํํ์๋ค.
๋ฐ๋ผ์ ์ค๋ณต ID๊ฐ ๋ฐ๊ฒฌ๋๋ฉด, ๊ฐ์
์ด ๋์ง ์๊ณ โ์ด๋ฏธ ์กด์ฌํ๋ ID์
๋๋ค.โ๋ผ๋ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๋๋ก ํ๋ค.
app.post('/signup', async (req, res) => {
const { ID, nickname, email, password, confirmPassword } = req.body;
try {
const exists = await fetchUser(ID);
if (exists) {
return res.json({ success: false, message: '์ด๋ฏธ ์กด์ฌํ๋ ID์
๋๋ค.' });
}
if (!ID || !nickname || !email || !password || !confirmPassword) {
return res.json({ success: false, message: '๋ชจ๋ ํญ๋ชฉ์ ์
๋ ฅํด์ฃผ์ธ์.' });
}
if (password !== confirmPassword) {
return res.json({ success: false, message: '๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.' });
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return res.status(400).json({ success: false, message: '์ฌ๋ฐ๋ฅธ ์ด๋ฉ์ผ ํ์์ด ์๋๋๋ค.' });
}
const newUser = { ID, nickname, email, password, createdAt: new Date().toISOString() };
await createUser(newUser);
return res.json({ success: true, message: 'ํ์๊ฐ์
์ด ์๋ฃ๋์์ต๋๋ค.' });
} catch (error) {
console.error('ํ์๊ฐ์
์๋ฌ:', error);
return res.status(500).json({ success: false, message: 'ํ์๊ฐ์
์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.' });
}
});
newUser ๋ณ์๋ฅผ ๋ง๋ค์ด ์๋ก์ด ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๋ด์๋ค.
๊ทธ๋ฆฌ๊ณ createUser(newUser)๋ก ์๋ก์ด ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ค.
๐ป ๋ฐฑ์๋ - ๋ง์ดํ์ด์ง ์ฝ๋ ๊ตฌํ ๋ณด๋ฌ๊ฐ๊ธฐ