본문 바로가기

JavaScript

Node.js 숙련 주차 개인 과제_1

728x90

Node.js 숙련 주차 개인 과제_1

 

📌 회원가입 & 로그인 API

회원가입, 로그인 API [출처 : 스타르타코딩클럽]


📌 Terminal

npm init -y

npm i sequelize mysql2 -S
npm i sequelize-cli -D

npx sequelize init

 

📄 /config/config.json

  "development": {
    "username": "root",
    "password": "비밀번호",
    "database": "database_development",
    "host": "엔드포인트",
    "dialect": "mysql"
  },

 

📌 기존 User 테이블 삭제

쿼리문

DROP TABLE `database_development`.`Users`
DROP TABLE `database_development`.`SequelizeMeta`

 

📌 User 모델 생성(Terminal)

npx sequelize model:generate --name User --attributes nickname:string,password:string

Id → UserId 수정

 

📄 /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,
    },
    nickname: DataTypes.STRING,
    password: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'User',
  });
  return User;
};

 

📄 /migrations/숫자-create-user.js 파일

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

 

📌 테이블 생성하기(Terminal)

npx sequelize db:migrate

User Table 생성 확인


회원가입

 

📌 Terminal

npm install express
npm install --save jsonwebtoken

 

📄 app.js

const express = require("express");
const { Op } = require("sequelize");
const jwt = require("jsonwebtoken");
const { User } = require("./models");
const authMiddleware = require("./middlewares/auth-middleware");

const router = express.Router();

const app = express();

app.use(express.json());


// 회원가입
router.post("/signup", async (req, res) => {
  
  try{
    const { nickname, password, confirm } = req.body;

    if(!/^([a-zA-z0-9]).{2,}$/.test(nickname)) {
      res.status(412).send({
          errorMessage: "ID의 형식이 일치하지 않습니다.",
      });
      return;
    }

    if(!/^([a-zA-z0-9]).{3,}$/.test(password)) {
      res.status(412).send({
        errorMessage: "패스워드 형식이 일치하지 않습니다.",
      });
      return;
    }

    if(password.search(nickname) > -1) {
      res.status(412).send({
        errorMessage: "패스워드에 닉네임이 포함되어 있습니다.",
      });
      return;
    }
 
    if (password !== confirm) {
      res.status(412).send({
        errorMessage: "패스워드가 일치하지 않습니다.",
      });
      return;
    }
  
    const existUser = await User.findAll({ where: { nickname } });
    if (existUser.length) {
      res.status(412).send({
        errorMessage: "중복된 닉네임입니다.",
      });
      return;
    }
  
    await User.create({ nickname, password });
  
    res.status(201).send({ message: "회원 가입에 성공하였습니다." });

  } catch(error) {
    res.status(400).send({
      errorMessage: "요청한 데이터 형식이 올바르지 않습니다."
    });
  }

});

app.use("/api", express.urlencoded({ extended: false }), router);

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

 

📌 ThunderClient

[POST] url : http://localhost:8080/api/signup

회원가입


로그인

 

 

📄 app.js

// 로그인
router.post("/login", async (req, res) => {
  try{
    const { nickname, password } = req.body;

    const user = await User.findOne({ where: { nickname, password } });

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

    const token = jwt.sign({ userId: user.userId }, 
      "customized-secret-key",
      { expiresIn: "1d" }
    );
    res.json({"token": token});

  } catch(error) {
    res.status(400).json({
      errorMessage: "로그인에 실패하였습니다."
    });
  }
  
});

 

📌 ThunderClient

[POST] url : http://localhost:8080/api/login

로그인 성공

 

📌 발급받은 토큰

UserId : 1

만료기간 : 1day

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsImlhdCI6MTY3MTY3Njk0NiwiZXhwIjoxNjcxNzYzMzQ2fQ.GX0sFegcxbH4B4mX994NqrfRJbmSbqRPg8Ir5tLHMcQ"
}

 

UserId : 2

만료기간 : 1day

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIsImlhdCI6MTY3MTY3ODA5NSwiZXhwIjoxNjcxNzY0NDk1fQ.zaiFCRBx9_odl688SvlmlIBTnCuXtmqSaZC_BKD42W4"
}

Token 유효성 검사

 

📄 /middlewares/auth-middleware.js

// middlewares/auth-middleware.js

const jwt = require("jsonwebtoken");
const { User } = require("../models");

module.exports = (req, res, next) => {
  const { authorization } = req.headers;
  const [authType, authToken] = (authorization || "").split(" ");

  if (!authToken || authType !== "Bearer") {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
    return;
  }

  try {
    const { userId } = jwt.verify(authToken, "customized-secret-key");
    User.findByPk(userId).then((user) => {
      res.locals.user = user;
      next();
    });
  } catch (err) {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
  }
};

'JavaScript' 카테고리의 다른 글

Node.js 숙련 주차 개인 과제_3  (0) 2022.12.23
Node.js 숙련 주차 개인 과제_2  (1) 2022.12.22
Node.js 숙련 1주차_6  (1) 2022.12.21
Node.js 숙련 1주차_5  (0) 2022.12.21
Node.js 숙련 1주차_4  (0) 2022.12.20