Node.JS : 블로그 구현하기_Router 작성

C_Mungi·2025년 6월 8일

Node.JS 학습

목록 보기
5/6
post-thumbnail

1. 시작

이전 포스트에서는 DB연동, View 및 Layout을 구현했다.
이제 남은 항목들은 도메인의 Router, Controller, Service 로직만을 앞두고 있다.
이번 포스트에서는 다음과 같이 작성한 Router 로직을 기록하고자 한다.

  • routes
    • postRouter.js : 게시글 관련 Router
    • adminRouter.js : 관리자 관련 Router

2. postRouter.js

postRouter에서는 요청 받은 endpoint에 맞춰 알맞은 게시글 관련 데이터를 보내줄 수 있도록 연결한다.

요청 받는 endpoint는 다음과 같다.

  • /, /home
    • GET : 메인 페이지에 표시할 게시글 리스트 조회
  • /posts/:id
    • GET : 특정 게시글의 상세 조회
  • /allPosts
    • GET : 게시글 조회 API
  • /add
    • GET : 게시글 작성 페이지로 랜더링
    • POST : 게시글 작성 API
  • /edit/:id
    • GET : 게시글 수정 페이지로 랜더링
    • PUT : 게시글 수정 API
  • /delete/:id
    • DELETE : 게시글 삭제 API
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;

3. adminRouter.js

adminRouter에서 요청 받는 endpoint는 다음과 같다.

  • /admin
    • GET : 로그인 페이지로 랜더링
    • POST : 로그인 API
  • /logout
    • GET : 로그아웃 API
  • /about
    • GET : About 페이지로 랜더링
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;

4. Util 클래스 작성

현재 상황에서 URL로 직접 관리자 페이지로 접속을 시도하면 어떠한 인증도 없이 관리자 페이지에 접속이 될 것이다.
당연히 NG인 상황이기에 인증을 거쳐야만 관리자 페이지에 접속할 수 있도록 해야한다.
다만, 현업에서 사용하는 방법은 훨씬 다양하고 복잡하므로 아래의 인증 로직은 어디까지나 참고정도로만 하면 될 것 같다.

  • utiles
    • authUtil.js

4-1. authUtil.js

const 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 };
profile
백엔드 개발자의 수집상자

0개의 댓글