
이전 포스트에서는 DB연동, View 및 Layout을 구현했다.
이제 남은 항목들은 도메인의 Router, Controller, Service 로직만을 앞두고 있다.
이번 포스트에서는 다음과 같이 작성한 Router 로직을 기록하고자 한다.
routespostRouter에서는 요청 받은 endpoint에 맞춰 알맞은 게시글 관련 데이터를 보내줄 수 있도록 연결한다.
요청 받는 endpoint는 다음과 같다.
const express = require("express");
const asyncHandler = require("express-async-handler");
const router = express.Router();
const postController = require("../controllers/postController");
const { checkLogin } = require("../utils/authUtil");
const adminLayout = "../views/layouts/admin-login.ejs";
router.get(["/", "/home"], asyncHandler(postController.getAllPost));
router.get("/posts/:id", asyncHandler(postController.getPostDetail));
router.get("/allPosts", checkLogin, asyncHandler(postController.getAllPostByAdmin));
router.route("/add")
.get(checkLogin, (req, res) => {
const locals = { title: "게시물 작성" };
res.render("admin/add", { locals, layout: adminLayout });
})
.post(checkLogin, asyncHandler(postController.addPost));
router.route("/edit/:id")
.get(checkLogin, async (req, res) => {
const locals = { title: "게시물 수정" };
const data = await postService.fetchPostById(req.params.id);
res.render("admin/edit", { locals, data, layout: adminLayout });
})
.put(checkLogin, asyncHandler(postController.editPost));
router.delete("/delete/:id", checkLogin, asyncHandler(postController.deletePost));
module.exports = router;
adminRouter에서 요청 받는 endpoint는 다음과 같다.
const express = require("express");
const router = express.Router();
const asyncHandler = require("express-async-handler");
const adminController = require("../controllers/adminController");
const { checkLogin } = require("../utils/authUtil");
const adminLoginLayout = "../views/layouts/admin-login.ejs";
const adminNoLoginLayout = "../views/layouts/admin-nologin.ejs";
const mainLayout = "../views/layouts/main.ejs";
router.route("/admin")
.get((req, res) => {
const locals = { title: "관리자 페이지" };
res.render("admin/login", { locals, layout: adminNoLoginLayout });
})
.post(asyncHandler(adminController.login));
router.route("/logout").get(adminController.logout);
router.route("/about").get((req, res) => {
const layout = isAdmin(req) ? adminLoginLayout : mainLayout;
const locals = { title: "About" };
res.render("admin/about", { locals, layout: layout });
});
module.exports = router;
현재 상황에서 URL로 직접 관리자 페이지로 접속을 시도하면 어떠한 인증도 없이 관리자 페이지에 접속이 될 것이다.
당연히 NG인 상황이기에 인증을 거쳐야만 관리자 페이지에 접속할 수 있도록 해야한다.
다만, 현업에서 사용하는 방법은 훨씬 다양하고 복잡하므로 아래의 인증 로직은 어디까지나 참고정도로만 하면 될 것 같다.
utilesconst jwt = require("jsonwebtoken");
const jwtSecret = process.env.JWT_SECRET;
const checkLogin = (req, res, next) => {
const token = req.cookies.token;
if (!token) {
return res.redirect("/admin");
}
try {
const payload = jwt.verify(token, jwtSecret);
req.userId = payload.userId;
next();
} catch (error) {
return res.redirect("/admin");
}
};
const isAdmin = (req) => {
const token = req.cookies?.token;
if (!token) {
return false;
}
try {
jwt.verify(token, jwtSecret);
return true;
} catch (e) {
return false;
}
};
module.exports = { checkLogin,isAdmin };