[TIL] Node.js 숙련 (3) 23.06.21

이상훈·2023년 6월 22일
0

[내일배움캠프]

목록 보기
32/68

✔️오늘 한일!

  • ERD 작성
  • 기존 mongoose 방식을 sequelize 방식으로 변경
  • 마이그레이션 파일 수정
  • CRUD -> sequelize 문법으로 수정

1)게시글 전체조회 및 상세조회

// 게시글 전체조회
router.get("/posts", async (req, res) => {
  const showPost = await Posts.findAll({
    attributes: ["postId", "userId", "title", "nickname", "createdAt", "updatedAt"],
    order: [["createdAt", "DESC"]],
  });

  try {
    if (!showPost.length) {
      return res.status(404).json({ message: "게시글이 없습니다." });
    }

    res.status(200).json({
      showPost: showPost,
    });
  } catch (err) {
    res.status(400).json({
      message: "게시글 조회에 실패하였습니다.",
    });
  }
});

기존에는 map()메서드로 출력할 목록들을 따로 만들어서 작동했는데 find()메서드의 attributes속성을 이용하여 코드 수정

게시글 수정/삭제

//게시글 수정
router.put("/posts/:postId", authMiddleware, async (req, res) => {
  const { postId } = req.params;
  const { userId } = res.locals.user;
  const { title, content } = req.body;

  try {
    const modifyPost = await Posts.findOne({ where: { postId } });
    if (!modifyPost) {
      return res.status(404).json({ message: "해당 게시글을 찾을 수 없습니다." });
    } else if (!title || !content) {
      return res.status(400).json({ message: "데이터를 입력해주세요." });
    } else if (modifyPost.UserId !== userId) {
      return res.status(401).json({ message: "수정권한이 없습니다." });
    } else {
      await Posts.update(
        { title, content },
        { where: { [Op.and]: [{ postId }, { UserId: userId }] } }
      );
      res.status(201).json({
        message: "게시글 수정 완료",
        Detail: {
          title: modifyPost.title,
          content: modifyPost.content,
          updatedAt: modifyPost.updatedAt,
        },
      });
    }
  } catch (err) {
    res.status(400).json({
      message: "게시글 수정에 실패하였습니다.",
    });
  }
});

userId를 비교하여 현재 로그인 한 아이디가 아니라면 수정 또는 삭제 권한이 없게하고 일치하는 유저만 가능하게 구현

회원가입

// 회원가입
router.post("/signup", async (req, res) => {
  const { email, nickname, password, confirmPassword } = req.body;
  const savedUsers = await Users.findOne({
    where: {
      [Op.or]: [{ email }, { nickname }],
    },
  });
  let regExp = /[ \{\}\[\]\/?.,;:|\)*~`!^\-_+┼<>@\#$%&\'\"\\\(\=]/;

  console.log(savedUsers);
  try {
    if (nickname.length <= 3 || regExp.test(nickname)) {
      res.status(412).json({
        message: "닉네임은 최소 3자 이상이여야 하며, 특수문자 및 공백을 사용할 수 없습니다.",
      });
      return;
    } else if (password.length <= 4 || password === nickname) {
      res.status(412).json({
        message: "비밀번호는 최소 4자 이상이여야 하며, 닉네임과 같은 값이 포함될 수 없습니다.",
      });
      return;
    }

    if (password !== confirmPassword) {
      res.status(412).json({
        message: "입력한 비밀번호와 비밀번호 확인값이 일치하지 않습니다.",
      });
      return;
    }

    if (savedUsers) {
      res.status(412).json({
        message: "이메일 또는 닉네임이 이미 사용중입니다.",
      });
      return;
    }

    const user = await Users.create({ email, nickname, password });

    return res.status(201).json({
      message: "회원가입이 완료되었습니다.",
    });
  } catch (err) {
    res.status(400).json({
      message: "요청한 데이터 형식이 올바르지 않습니다.",
    });
  }
});

회원가입에 대한 예외처리를 작성(닉네임 특수문자 사용불가, 길이수 제한 등)하고 회원가입 완료 시 유저의 email, nickname, password 정보를 DB에 저장

로그인

// 로그인 API
router.post("/login", async (req, res) => {
  const { email, password } = req.body;
  const user = await Users.findOne({ where: { email } });

  try {
    if (!user || password !== user.password) {
      res.status(400).json({
        errorMessage: "이메일 또는 패스워드가 틀렸습니다.",
      });
      return;
    }

    const token = jwt.sign({ userId: user.userId }, "customized-secret-key", { expiresIn: "30m" });

    res.cookie("authorization", `Bearer ${token}`);
    res.status(200).json({
      token,
      message: "로그인에 성공하였습니다.",
    });
  } catch (err) {
    res.status(400).json({
      message: "로그인에 실패하였습니다.",
    });
  }
});

DB에 있는 유저정보와 비교, 로그인에 성공하였다면 토큰을 발행하고 토큰의 만료기간은 30분으로 설정


API명세서와 README 작성 후 제출하면 이번 과제도 끝날 것 같다. 코드리뷰를 꼼꼼히 하고 Node 강의를 다시 복습해볼 예정이다.

profile
코린이

0개의 댓글