[내배캠] TIL, WIL/TIL

노드js

값싼외노자 2022. 12. 22. 09:21

app.js

const express = require("express");
// const mongoose = require("mongoose");
// mongoose.set('strictQuery', true);
const { post } = require("./models");
const { User } = require("./models");
const { comment } = require("./models");
const jwt = require('jsonwebtoken');
const router = express.Router();
const app = express();

const { Op } = require("sequelize");

const authMiddleware = require('./middlewares/auth-middlewares');

// mongoose.connect("mongodb://127.0.0.1:27017/shopping-demo", {
//   useNewUrlParser: true,
//   useUnifiedTopology: true,
// });
// const db = mongoose.connection;
// db.on("error", console.error.bind(console, "connection error:"));


app.use(express.json());
app.use("/api", express.urlencoded({ extended: false }), router); // urlencoded는 미들웨어, 즉 /api로 들어온것은 urlencoded 미들웨어를 거친다음 라우터로 가라 라는 뜻
app.use(express.static("assets")); // 정적 파일을 서빙해준다.

// 회원가입 기능 몽구스 버전
// const User = require('./models/user')
// router.post('/users', async(req,res) => {
//     const {nickname, email, password, confirmPassword} = req.body;

//     // 1. 패스워드와 패스워드확인 값이 일치하는가
//     // 2. 이메일과 닉네임 중복인가
//     // 3. db에 삽입

//     if (password !== confirmPassword) {
//         res.status(400).json({errorMessage:"비밀번호 확인이 일치하지 않습니다."});
//         return; // 위에 패스워드가 일치하지 않으면 밑에 코드를 더 실행하면 안되니까 여기서 리턴해준다
//     }
//     const existUser = await User.findOne({
//         $or: [{email: email},{nickname:nickname}] // $or << 이안에 있는 값중에 하나라도 일치했을 때 보여준다.
//     }); // 그리고 값중에 하나라도 일치한다는 뜻은 이메일이나 닉네임 중 중복이 있다는 뜻이기에 더 진행해선 안된다.
    
//     if (existUser) {
//         res.status(400).json({errorMessage:"이메일이나 닉네임이 중복됩니다."})
//         return; // 중복되면 회원가입이 되면 안되기에 여기서 리턴하여 코드를 종료시킨다.
//     }
    
//     // 여기까지 위의 두 if문을 거치지 않았다면 회원가입이 정상적으로 실행되어야 한다.
//     const user = new User({nickname,email,password});
//     await user.save();
    
//     res.status(201).json({}); // 스테이터스 201은 무언가를 만들었다는 creat 생성 코드! 기억하면 좋음
// });



// 위 부터 회원가입 mysql 시퀄라이즈 버전


router.post("/users", async (req, res) => {
    const { email, nickname, password, confirmPassword } = req.body;
    console.log('콘솔로그 :' , req.body)
    if (password !== confirmPassword) {
      res.status(400).send({
        errorMessage: "패스워드가 패스워드 확인란과 다릅니다.",
      });
      return;
    }

    if (nickname.length < 3){
        res.status(400).send({
            errorMessage: "닉네임은 최소 3글자 이상이어야 합니다."
        })
        return;
    }

    if (password.length < 4) {
        res.status(400).send({
            errorMessage: "비밀번호는 최소 4자 이상이어야 합니다."
        })
        return;
    }

    if (password.includes(nickname) === true) {
        res.status(400).send({
            errorMessage: "비밀번호 안에 닉네임이 포함될 수 없습니다."
        })
        return;
    }
  
    // email or nickname이 동일한게 이미 있는지 확인하기 위해 가져온다.
    const existsUsers = await User.findAll({
      where: {
        [Op.or]: [{ email }, { nickname }],
      },
    });
    if (existsUsers.length) {
      res.status(400).send({
        errorMessage: "이메일 또는 닉네임이 이미 사용중입니다.",
      });
      return;
    }
  
    await User.create({ email, nickname, password });
    res.status(201).json({message:"회원가입 완료!"});
  }); // 회원가입


// 로그인 기능 몽구스버전
// router.post('/auth', async(req,res) => {
//     const {email,password} = req.body;

//     const user = await User.findOne({email}); // 특정 사용자를 이메일을 바탕으로 먼저 찾을 것 .
   
//     // 1. 로그인이 가능하지 않을 경우를 먼저 구현하는데 우선 사용자가 존재하지 않거나
//     // 2. 입력받은 패스워드와 사용자의 패스워드가 다를 때 에러 메세지를 발생 시켜야 한다.
   
//     if (!user || password !== user.password) { 
//         res.status(400).json({errorMessage:"로그인 정보가 일치하지 않습니다."})
//         return;
//     }

//     // 이제는 위의 if문을 거치지 않는다면 사용자 정보가 일치한다는 뜻이니 로그인이 되어야한다. 

//     const token = jwt.sign({userId:user.userId},'juho-secretkey') // 여기서 user.userId의 userId는 /models/user.js에서 8번줄인 _id값이란 뜻이다.
//     // 즉, user.userId는 user._id와 같다는 뜻!

//     res.status(200).json({
//         "token":token,
//     })
// })

router.post("/auth", async (req, res) => { 
    // 로그인 기능 mysql 시퀄라이저버전
    const { email, password } = req.body;
  
    const user = await User.findOne({
      where: {
        email,
      },
    });
  
    // NOTE: 인증 메세지는 자세히 설명하지 않는것을 원칙으로 한다: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#authentication-responses
    if (!user || password !== user.password) {
      res.status(400).send({
        errorMessage: "이메일 또는 패스워드가 틀렸습니다.",
      });
      return;
    }
  
    res.send({
      token: jwt.sign({ userId: user.userId }, "customized-secret-key"),
    });
    console.log(token)
    
  }); // 로그인

// 전체 게시글 보기
router.get('/post', async (req,res) => {
  const all_post = await post.findAll({})
  res.status(200).json({all_post})
})

// 게시글 작성
router.post("/post", async (req, res) => {
  const { post_title, post_content, post_user } = req.body;
  await post.create({ post_title, post_content, post_user });
  res.status(201).json({message:"게시글 작성 완료!"})
});


// 모든 댓글 보기
router.get('/comment', async (req,res) => {
  const all_comment = await comment.findAll({})
  res.status(200).json({success:all_comment})
})

// 댓글 작성
router.post('/comment', async (req,res) => {
  // const {post_id} = req.params;
  const {comment_content,comment_user} = req.body;

  if (comment_content === undefined){
    return res.status(400).json({errorMessage:"댓글 내용을 입력해주세요."})
  }

  await comment.create({
    comment_content,comment_user
  })
  res.status(201).json({message:"댓글 작성 완료!!"});
})

// 댓글 삭제
router.delete('/comment/:comment_id', async (req,res) => {
  const {comment_id} = req.params
  console.log(comment_id);
  await comment.destroy({
    where: { comment_id: comment_id },
});
  res.status(200).json({success:"댓글을 삭제하였습니다."})
})


// 댓글 수정
router.put('/comment/:comment_id', async (req,res) => {
  const {comment_id} = req.params
  const {comment_content} = req.body

  if (comment_content === undefined){
      return res.status(400).json({errorMessage:"수정할 내용을 입력해주세요."})
  }

  await comment.update({comment_content: comment_content}, {
          where: { comment_id: comment_id },
      });
  res.status(200).json({success:"댓글을 수정하였습니다."})
})


app.listen(8080, () => {
  console.log("서버가 요청을 받을 준비가 됐어요");
});

./models/user.js

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  };
  User.init({
    userId: {
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    email: DataTypes.STRING,
    nickname: DataTypes.STRING,
    password: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'User',
  });
  return User;
};

./models/post.js

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class post extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  post.init({
    post_id: {
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    post_title: DataTypes.STRING,
    post_content: DataTypes.TEXT,
    post_user: DataTypes.INTEGER
  }, {
    sequelize,
    modelName: 'post',
  });
  return post;
};

./models/comment

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class comment extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  comment.init({
    comment_id: {
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    comment_content: DataTypes.TEXT,
    comment_user: DataTypes.INTEGER
  }, {
    sequelize,
    modelName: 'comment',
  });
  return comment;
};

./migrations/create-user.js

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Users', {
      userId: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      email: {
        type: Sequelize.STRING
      },
      nickname: {
        type: Sequelize.STRING
      },
      password: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('Users');
  }
};

./migrations/create-comment

'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('comments', {
      comment_id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      comment_content: {
        type: Sequelize.TEXT
      },
      comment_user: {
        type: Sequelize.INTEGER
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('comments');
  }
};

./migrations/create-post.js

'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable('posts', {
      post_id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      post_title: {
        type: Sequelize.STRING
      },
      post_content: {
        type: Sequelize.TEXT
      },
      post_user: {
        type: Sequelize.INTEGER
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable('posts');
  }
};

'[내배캠] TIL, WIL > TIL' 카테고리의 다른 글

노드JS 스웨거  (0) 2022.12.26
로그인 문제  (0) 2022.12.23
자바 스크립트  (0) 2022.12.21
자바 스크립트  (0) 2022.12.19
알고리즘  (0) 2022.12.19