wic-api - 1

업데이트:

Express 시작하기

Express는 NodeJS 기반으로 WAS를 만들 수 있는 라이브러리다.
편한 시작을 위해 boilerplate인 express-generator 을 사용하려고 한다.

Express generator

1
2
$ npm install -g express-generator
$ express <project name>+

Project Tree

아래와 같은 구조로 프로젝트를 수정했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wic-api
├─ .dockerignore
├─ .gitignore
├─ app.js
├─ bin
│  └─ www
├─ Dockerfile
├─ models
│  └─ user.js
├─ package-lock.json
├─ package.json
└─ routes
   ├─ auth.js
   ├─ chatbot.js
   ├─ esd.js
   └─ workspace.js

mongo 연동

mongo 컨테이너를 27017 포트로 띄우면서, 저장소를 로컬 디스크에 마운트했다.

1
$ docker run --name mongo -v C:\\mongo-mount:/data/db -d -p 27017:27017 mongo

mongo connector 라이브러리인 ‘mongoose’를 설치했다.

1
$ npm install mongoose

MVC 패턴의 ‘M’을 구현한다.
(models/user.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const mongoose = require('mongoose');

// Define Schemes
const userSchema = new mongoose.Schema({
  userId: { type: String, required: true, unique: true },
  password: { type: String, required: true }
},
{
  timestamps: true
});

// Create new user document
userSchema.statics.create = function (payload) {
  // this === Model
  const user = new this(payload);
  // return Promise
  return user.save();
};

// Find All
userSchema.statics.findAll = function () {
  // return promise
  return this.find({});
};

// Find One by userId
userSchema.statics.findOneByuserId = function (userId) {
  return this.findOne({ userId });
};

// Update by userId
userSchema.statics.updateByuserId = function (userId, payload) {
  // { new: true }: return the modified document rather than the original. defaults to false
  return this.findOneAndUpdate({ userId }, payload, { new: true });
};

// Delete by userId
userSchema.statics.deleteByuserId = function (userId) {
  return this.remove({ userId });
};

// Create Model & Export
module.exports = mongoose.model('user', userSchema);

auth.js Route 구현

join, login의 구현이다.
비밀번호를 저장할 때, .env의 HASH_SALT를 활용해 mongo에 저장된다.
(routes/auth.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const express = require('express');
const router = express.Router();
const CryptoJS = require('crypto-js');
const User = require('../models/user');
require('dotenv').config();
const { HASH_SALT } = process.env;

// 회원가입
router.post('/join', function(req, res, next) {
  const { userId, password } = req.body;

  if (!userId) return res.status(400).send("field 'userId' is required.");
  if (!password) return res.status(400).send("field 'password' is required.");

  /**
   * TODO: password 규칙 체크
   */

  const hashedPassword = CryptoJS.SHA256(password + HASH_SALT).toString();

  User.create(req.body)
    .then( user => res.status(201).send({userId, hashedPassword}) )
    .catch( err => {
      let message = "exceptional error";

      if (err.code == 11000) {
        message = "key duplicated";
      }

      res.status(500).send(message);
    } );
});

// 로그인
router.post('/login', function(req, res, next) {
  /* check */
  if (!req.body.userId) return res.status(400).send("field 'userId' is required.");
  if (!req.body.password) return res.status(400).send("field 'password' is required.");
  
  User.findOne(req.body)
    .then( result => result ? res.send("ok") : res.status(400).send("fail") )
    .catch( err => res.status(500).send(err) );
});

module.exports = router;

댓글남기기