111 lines
3 KiB
JavaScript
111 lines
3 KiB
JavaScript
/**
|
|
* 인증 라우터
|
|
* 로그인 및 토큰 검증
|
|
*/
|
|
const express = require("express");
|
|
const router = express.Router();
|
|
const jwt = require("jsonwebtoken");
|
|
const bcrypt = require("bcryptjs");
|
|
const { Op } = require("sequelize");
|
|
const User = require("../models/User");
|
|
const SystemConfig = require("../models/SystemConfig");
|
|
|
|
const JWT_SECRET =
|
|
process.env.JWT_SECRET || "super_secret_jwt_key_changed_in_production";
|
|
|
|
/**
|
|
* 로그인
|
|
* POST /api/login
|
|
* - 이메일 또는 아이디(@ 없이)로 로그인 가능
|
|
*/
|
|
router.post("/login", async (req, res) => {
|
|
let { email, password } = req.body;
|
|
try {
|
|
// 아이디로 로그인 시도 시 (@ 없이 입력) 전체 이메일 조회
|
|
if (!email.includes("@")) {
|
|
const user = await User.findOne({
|
|
where: { email: { [Op.like]: `${email}@%` } },
|
|
});
|
|
if (user) email = user.email;
|
|
}
|
|
|
|
const user = await User.findOne({ where: { email } });
|
|
if (!user) {
|
|
return res.status(401).json({ error: "잘못된 자격 증명입니다." });
|
|
}
|
|
|
|
const isMatch = await bcrypt.compare(password, user.password);
|
|
if (!isMatch) {
|
|
return res.status(401).json({ error: "잘못된 자격 증명입니다." });
|
|
}
|
|
|
|
// DB에서 세션 만료 시간 조회 (기본값: 24시간)
|
|
let expireHours = 24;
|
|
try {
|
|
const config = await SystemConfig.findByPk("session_expire_hours");
|
|
if (config && config.value) {
|
|
expireHours = parseInt(config.value) || 24;
|
|
}
|
|
} catch (e) {
|
|
console.error("세션 설정 조회 오류:", e);
|
|
}
|
|
|
|
// JWT 토큰 생성
|
|
console.log(`[로그인] ${user.email} - 세션 만료 시간: ${expireHours}시간`);
|
|
const token = jwt.sign(
|
|
{ id: user.id, email: user.email, isAdmin: user.isAdmin },
|
|
JWT_SECRET,
|
|
{ expiresIn: `${expireHours}h` }
|
|
);
|
|
|
|
res.json({
|
|
success: true,
|
|
token,
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
name: user.name,
|
|
isAdmin: user.isAdmin,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error("로그인 오류:", error);
|
|
res.status(500).json({ error: "서버 내부 오류" });
|
|
}
|
|
});
|
|
|
|
/**
|
|
* 토큰 검증 및 최신 사용자 정보 조회
|
|
* GET /api/verify
|
|
* - 토큰 검증 후 DB에서 최신 사용자 정보 가져옴
|
|
*/
|
|
router.get("/verify", async (req, res) => {
|
|
const token = req.headers.authorization?.split(" ")[1];
|
|
if (!token) return res.status(401).json({ valid: false });
|
|
|
|
try {
|
|
const decoded = jwt.verify(token, JWT_SECRET);
|
|
|
|
// DB에서 최신 사용자 정보 조회
|
|
const user = await User.findByPk(decoded.id);
|
|
if (!user) {
|
|
return res
|
|
.status(401)
|
|
.json({ valid: false, error: "사용자를 찾을 수 없습니다" });
|
|
}
|
|
|
|
res.json({
|
|
valid: true,
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
name: user.name,
|
|
isAdmin: user.isAdmin,
|
|
},
|
|
});
|
|
} catch (err) {
|
|
return res.status(401).json({ valid: false });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|