본문 바로가기
JS/Node.js

TIL(23.06.21) - 게시글 / 댓글 RestAPI 구현

by 썸맨 2023. 6. 22.

★ 개인 프로젝트(spa_blog)에서 게시글 / 댓글 API 

1) 회원가입 POST(/signup)

    const { nickname, password, confirmPassword } = req.body;
    let nicknameReg = new RegExp(/^[\w]{3,12}$/g);

    if (!nickname || !password || !confirmPassword) {
      res.status(412).json({
        success: false,
        errorMessage: "닉네임, 비밀번호, 비밀번호 확인을 전부 입력해 주세요.",
      });
      return;
    }

    if (!nicknameReg.test(nickname)) {
      res.status(412).json({
        success: false,
        errorMessage: "닉네임은 3 ~ 12자리이면서 알파벳이나 숫자로만 구성해주세요.",
      });
      return;
    }

    if (password.length < 4 || password.includes(nickname)) {
      res.status(412).json({
        success: false,
        errorMessage: "패스워드는 4자리이상이고 닉네임과 같은 값이 포함이 되면 안됩니다.",
      });
      return;
    }

    if (password !== confirmPassword) {
      res.status(412).json({
        success: false,
        errorMessage: "패스워드와 패스워드확인이 다릅니다.",
      });
      return;
    }

 => 정규형 사용해서 3~12자리 숫자와 문자만 포함되도록 지정해서 아이디에 Validation Check하고 요구사항에 필요한 유효성 검사도 전부 추가했음

 

 

2) 로그인 POST(/login)

const jwt = require("jsonwebtoken");
 
    const { nickname, password } = req.body;
    const user = await User.findOne({ nickname });

    if (!user || user.password !== password) {
      res.status(412).json({
        success: false,
        errorMessage: "닉네임 또는 패스워드를 확인해주세요. ",
      });
      return;
    }

    const token = jwt.sign({ userId: user.userId }, "secret-login-key", { expiresIn: "1h" });

    res.cookie("Authorization", `Bearer ${token}`);

=> 해당 닉네임이 없거나 비밀번호가 다르면 반환되는 유효성 검사 후 토큰을 만들어서 저장이 되도록 구현(이 때, 1시간으로 만료 시간을 정함)

 

 

3) 게시글 등록하기POST 수정(/posts)

    const user = res.locals.user;
    const userNickname = res.locals.userNickname;
    const { title, content } = req.body;

    if (!title || !content)
      return res
        .status(412)
        .json({ success: false, errorMessage: "게시글의 정보가 입력되지 않았습니다." });

    await Post.create({ userId: user._id, nickname: userNickname, title, content });

=> jsonwebtoken으로 저장되어 있는 값에서 검증 후 검증에 문제가 없다면 res.locals.user와 res.locals.userNickname을 가져와 게시글을 저장할 때 해당 로그인이 되어 있는 정보도 같이 저장하도록 수정

 

 

4) 게시글 수정PUT 수정(/posts/:postid)

    const { postId } = req.params;
    const { userId } = res.locals.user;
    const { title, content } = req.body;

    const existPost = await Post.findById(postId);

    if (!existPost)
      return res
        .status(404)
        .json({ success: false, errorMessage: "해당 게시글을 찾을 수 없습니다." });

    if (userId !== existPost.userId)
      return res
        .status(403)
        .json({ success: false, errorMessage: "게시글 수정 권한이 존재하지 않습니다." });

    if (!title || !content)
      return res
        .status(412)
        .json({ success: false, errorMessage: "게시글 제목이나 내용이 빈 내용인지 확인해 주세요" });

=> 현재 로그인 되어 있는 값과 저장된 게시글의 userId를 비교해 같으면 수정할 수 있도록 하고 다르다면 수정을 할 수없도록 수정했음(삭제도 동일하게 구현 / 댓글도 게시글과 유사하게 구현했음)

 

 

5) middlewares폴더에 auth-middleware.js를 통해 미들웨어를 만들어서 로그인 시, 토큰이 저장이 되도록 구현

    const { Authorization } = req.cookies;

    const [authType, authToken] = (Authorization ?? "").split(" ");

    if (authType !== "Bearer" || !authToken) {
      res.status(403).json({
        success: false,
        errorMessage: "로그인 후에 이용할 수 있는 기능입니다.",
      });
      return;
    }

    const { userId } = jwt.verify(authToken, "secret-login-key");

    const user = await User.findById(userId);

    if (!user) {
      res.clearCookie("Authorization");
      res.status(403).json({ success: false, errorMessage: "토큰 사용자가 존재하지 않습니다." });
    }
    res.locals.user = user;
    res.locals.userNickname = user.nickname;

=> 로그인 시, cookie-parser미들웨어를 통해 해당 토큰을 보내 검증 후 로그인한 정보의 id값과 닉네임 값을 사용하기 위해 res.locals.user/userNickname에 저장

 

 

 

★ moongoose대신 sequelize를 사용 해 구현

 - find를 findOne, findAll로 변경하고 대부분은 같은 코드로 구현이 되었음(model 작성 시, user와 post 관계가 1:N 관계로만 설정되도록 변경하면 끝!)

./model/users.js
      this.hasMany(models.Posts, {
        sourceKey: "userId",
        foreignKey: "UserId",
      });
./model/posts.js
      this.belongsTo(models.Users, {
        targetKey: "userId",
        foreignKey: "UserId",
      });

 

 

※ , develop하기 전에 try~catch를 함수로 만들어서 사용했었는데, 이 함수를 미들웨어로 작성해 리팩토링을 해볼 계획

'JS > Node.js' 카테고리의 다른 글

TIL(2023.06.27)  (0) 2023.06.29
Node.js 숙련  (0) 2023.06.25
TIL(23.06.23) refreshToken을 활용한 유저 계정 전환 기능  (0) 2023.06.24
TIL(23.06.22) .env 설정 / refreshToken 생성  (0) 2023.06.24
Node.js 입문  (0) 2023.06.20