본문 바로가기
Others/42Seoul

BLIND CLONE CODING 4일차

by tonyhan18 2022. 1. 30.
728x90

서버쪽에서

```

npm i jsonwebtoken

```

---

 

const express = require("express");
const router = express.Router();
const jwt = require("jsonwebtoken");
const { Article, Comment, Reply } = require("../mongoose/model");

// 개별 게시글 가져오는 라우트
router.get("/article/:key", async (req, res) => {
  const { key } = req.params;
  const article = await Article.findOne({ key: key })
    .populate("board")
    .populate({
      path: "author",
      populate: { path: "company" },
    });

  const commentList = await Comment.find({ article: article._id }).populate({
    path: "author",
    populate: { path: "company" },
  });

  Promise.all(
    commentList.map(async (v) => {
      const replies = await Reply.find({ comment: v._doc._id }).populate({
        path: "author",
        populate: { path: "company" },
      });
      return {
        ...v._doc,
        author: {
          ...v._doc.author._doc,
          nickname: `${v._doc.author._doc.nickname[0]}${"*".repeat(
            v._doc.author._doc.nickname.length - 1
          )}`,
        },
        replies: replies.map((r) => {
          return {
            ...r._doc,
            author: {
              ...r._doc.author._doc,
              nickname: `${r._doc.author._doc.nickname[0]}${"*".repeat(
                r._doc.author._doc.nickname.length - 1
              )}`,
            },
          };
        }), // 대댓글 배열
      };
    })
  )
    .then((comment) => {
      res.send({
        article: {
          ...article._doc,
          author: {
            ...article._doc.author._doc,
            nickname: `${article.author._doc.nickname[0]}${"*".repeat(
              article._doc.author._doc.nickname.length - 1
            )}`,
          },
        },
        comment: comment,
      });
    })
    .catch(() => {});
});

// 게시글 추가
router.post("/article/create", async (req, res) => {
  const { title, content, board, image } = req.body;
  const { authorization } = req.headers;

  if (!authorization) {
    return res.send({
      error: true,
      msg: "토큰이 존재하지 않음",
    });
  }

  const token = authorization.split(" ")[1];
  const secret = req.app.get("jwt-secret");

  jwt.verify(token, secret, async (err, data) => {
    if (err) {
      res.send(err);
    }
    const payload = {
      author: data.id,
      title,
      content,
      board,
      articleImgAddress: image,
    };
    const newArticle = await Article(payload).save();
    res.send(newArticle);
  });
});

// 게시글 수정
router.patch("/article/update", async (req, res) => {
  const { id, author, content } = req.body;
  const updatedArticle = await Article.findOneAndUpdate(
    {
      _id: id,
      author,
    },
    {
      content,
    },
    {
      new: true,
    }
  );
  res.send(updatedArticle);
});

// 게시글 완전 삭제(HARD DELETE)
router.delete("/article/delete/hard", async (req, res) => {
  const { id, author } = req.body;
  a;
  const deletedArticle = await Article.deleteOne({
    _id: id,
    author,
  });
  res.send(deletedArticle);
});

// 게시글 소프트 삭제(SOFT DELETE)
router.delete("/article/delete/soft", async (req, res) => {
  const { id, author } = req.body;
  const deletedArticle = await Article.findOneAndUpdate(
    {
      _id: id,
      author,
    },
    {
      deleteTime: new Date().getTime() + 30 * 24 * 60 * 60 * 1000, // 30일 후의 시간이 저장
    }
  );
  res.send(deletedArticle);
});

module.exports = router;

 

jwt를 사용하는건 사용자의 정보 상태를 client side에 유지하는것도 그 유지된것에 

 

--

 

jwt로 사용자 인증하기2

프론트에서 사용자 정보와 관련된것은 토큰을 함께보내주면된다. 그런데 함께 보내주는 경우가 글쓰기, 댓글달기등의 경우가 있을것이다.

 

verify는 await가 작동하지 않으니 callBack으로 처리해주자

 

const getUserToken = async (req, res, next) => {
  const { authorization } = req.headers;
  if (!authorization) {
    return res.send(false);
  }
  if (authorization) {
    const token = authorization.split(" ")[1];
    const secret = req.app.get("jwt-secret");
    jwt.verify(token, secret, (err, data) => {
      if (err) {
        return res.send(err);
      }
      return res.send(true);
    });
  }
};

위와같이 하면 우리가 가진 데이터를 반환해준다.

 

이때 secretKey는 위의 방식으로 해놓으면 어디에서든 사용 가능해진다. 

 

우리가 숨겨놓은 정보를 모두 볼 수 있으니 토큰이 verify되었다는 것을 알 수 있다.

 

그런데 우리가 article이나 댓글 달때 author id를 직접넣었는데 이러면 해킹달할 위험이 있어서 안된다.

 

암튼 받은 데이터에서 nickname을 쉽게알 수 있으니 /article/create 부분을 수정하자. 그리고 author id가 아닌 loginUser._id를 토큰에 함께 넣어주어야 겠다.

 

router.post("/article/create", async (req, res) => {
  const { title, content, board, image } = req.body;
  const { authorization } = req.headers;

  if (!authorization) {
    return res.send({
      error: true,
      msg: "토큰이 존재하지 않음",
    });
  }

  const token = authorization.split(" ")[1];
  const secret = req.app.get("jwt-secret");

  jwt.verify(token, secret, async (err, data) => {
    if (err) {
      res.send(err);
    }
    const payload = {
      author: data.id,
      title,
      content,
      board,
      //articleImgAddress: image,
    };
    const newArticle = await Article(payload).save();
    res.send(newArticle);
  });
});

일단 /article/create 부분은 위와같이 작성해주자.

 

 

728x90

'Others > 42Seoul' 카테고리의 다른 글

Alumni Board 만들기  (0) 2022.02.18
[42] minitalk_2022 코드 복기  (0) 2022.02.17
BLIND CLONE CODING 3일차 - Nuxt FrontEnd  (0) 2022.01.24
BLIND CLONE CODING 2일차  (0) 2022.01.23
BLIND CLONE CODING 1일차  (0) 2022.01.22