관리 메뉴

프로그래밍 삽질 중

client(react)와 server(node.js) 연결하기 - 로그인 하기(서버부분) 본문

과거 프로그래밍 자료들/React

client(react)와 server(node.js) 연결하기 - 로그인 하기(서버부분)

평부 2022. 5. 11. 17:33

* 인프런의 "따라하며 배우는 노드, 리액트 시리즈 - 기본 강의" 내용 중 정리

 

 

server 부분 : node.js를 이용해 로그인 부분 만들기

1) mongoDB와 연결

2) users.js라는 스키마가 포함된 값 만들기(mongoDB와 연결됨)

3) 로그인 시 user.js값 확인 후 정보 가져오기

4) 정보가 맞는지 확인하기

5) 정보가 맞으면 logSuccess : true, 맞지 않으면 false

6) Postman으로 확인하기

 

1) mongoDB와 연결 - [index.js]

const express = require("express");
const app = express();

const bodyParser = require("body-parser"); 
const User = require("./models/User");

const cookieParser = require("cookie-parser");
const config = require("./config/key");
const mongoose = require("mongoose"); //mongdoDB 연결 1)
const { auth } = require("./middleware/auth");

//application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());

//mongoDB 연결 2)
mongoose
  .connect(config.mongoURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => console.log("MongoDB connected"))
  .catch((err) => console.log(err));

//메인 페이지
app.get("/", (req, res) => res.send("hello world"));

const port = 5000;
app.listen(port, () => console.log("node 시작"));

 

* config : mongDB 연결 시 local로 할 지 global로 할 지 결정하는 것 

- dev.js : mongoDB와 연결하는 코드 확인 (자세한 설명 : https://lowell-dev.tistory.com/36

- key.js : dev를 사용할지 prod.js 사용할 지 결정하는 코드

- prod.js : dev.js로 연결되지 않았을 경우 사용하는 코드

//dev.js
module.exports = {
  mongoURI:
    "mongoDB connect에서 확인 가능한 주소",
};

//key.js
if (process.env.NODE_ENV === "production") {
  module.exports = require("./prod");
} else {
  module.exports = require("./dev");
}


//prod.js
module.exports = {
  mongoURI: process.env.MONGO_URI,
};

* body-parser : HTTP 요청 시(POST, GET 같은 요청)  request body 에 들어오는 데이터값을 읽을 수 있는 구문으로 파싱함과 동시에 req.body 로 입력해주어 응답 과정에서 요청에 body 프로퍼티를 새로이 쓸 수 있게 해주는 미들웨어

-> req.body.name, req.body.email 등을 가능하게 함

(자세한 설명 : https://velog.io/@yejinh/express-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4-bodyParser-%EB%AA%A8%EB%93%88

 

* cookie-parser : Cookie 헤더를 파싱하고, 쿠키 이름에 의해 키가 지정된 객체로 req.cookies를 채운다.
secret 문자열을 전달하여 선택적으로 서명된(signed) 쿠키 지원을 활성화할 수 있다.
secret 문자열은 다른 미들웨어에서 사용할 수 있도록 req.secret을 할당한다.

(자세한 설명 : https://velog.io/@heony/cookie-parser)

 

 

 

 

2) users.js라는 스키마가 포함된 값 만들기(mongoDB와 연결됨) - [models/User.js]

const mongoose = require("mongoose"); //mongoDB와 연결
const bcrypt = require("bcrypt"); //암호화 시 사용
const saltRounds = 10; //bcrypt 사용 시 사용
const jwt = require("jsonwebtoken"); //토큰 생성 시 사용

const userSchema = new mongoose.Schema({
  name: { //이름
    type: String,
    maxlength: 50,
  },
  email: { //이메일
    type: String,
    trim: true,
    unique: 1,
  },
  password: { //비밀번호
    type: String,
    minlength: 5,
  }, 
  lastname: { //성
    type: String,
    maxlength: 50,
  },
  role: { //0이면 일반 유저, 1이면 관리자
    type: Number,
    default: 0,
  },
  image: String, //이미지
  token: { //토큰
    type: String,
  },
  tokenExp: { //토큰 만료일
    type: Number,
  },
});

module.exports = mongoose.model("User", userSchema);

 

3) 로그인 시 user.js값 확인 후 정보 가져오기

4) 정보가 맞는지 확인하기

5) 정보가 맞으면 logSuccess : true, 맞지 않으면 false

- ① index.js 추가 / ② models/User.js 추가

 

① index.js

//index.js
const User = require("./models/User"); //user값을 가져온다


app.post("/api/users/login", (req, res) => {
  //요청된 이메일이 데이터베이스에 있는지 찾는다
  User.findOne({ email: req.body.email }, (err, user) => {
    if (!user) { 
      return res.json({
        loginSuccess: false,
        message: "제공된 이메일에 해당되는 유저가 없습니다.",
      });
    }
    //요청된 이메일이 데이터베이스에 있다면 비밀번호가 같은지 확인한다
    user.comparePassword(req.body.password, (err, isMatch) => {
      if (!isMatch)
        return res.json({
          loginSuccess: false,
          message: "비밀번호가 틀렸습니다",
        });
      //비밀번호가 맞다면 토큰 생성
      user.generateToken((err, user) => {
        if (err) return res.status(400).send(err);
        //토큰을 저장한다 1. 쿠키 2. 로컬스토리지
        res
          .cookie("x_auth", user.token)
          .status(200)
          .json({ loginSuccess: true, userId: user._id });
      });
    });
  });
});

 

② models/User.js

* comparePassword, getnerateToken, isMatch는 User.js에서 만들어짐

const bcrypt = require("bcrypt"); //암호화 시 사용
const saltRounds = 10; //bcrypt 사용 시 사용
const jwt = require("jsonwebtoken"); //토큰 생성 시 사용

userSchema.methods.comparePassword = function (plainPassword, cb) {
  //위의 user 가져오기(userSchema 의미)
  var user = this;
  //plainPassword : 암호화 전 비밀번호 cb : 암호화된 비밀번호
  bcrypt.compare(plainPassword, user.password, function (err, isMatch) {
    if (err) return cb(err);
    cb(null, isMatch);
  });
};

userSchema.methods.generateToken = function (cb) {
  var user = this;

  //jsonwebtoken을 이용해 token 생성
  var token = jwt.sign(user._id.toHexString(), "secretToken");

  user.token = token;
  user.save(function (err, user) {
    if (err) return cb(err);
    cb(null, user);
  });
};

* jwt 사용법 : 공식 사이트 :  (https://www.npmjs.com/package/jsonwebtoken)

* token 사용법 : 공식 사이트 : (https://www.npmjs.com/package/token)

 

6) Postman으로 확인하기

- npm start 혹은 npm run dev로 서버 키기

 

① postman으로 확인하기

② mongoDB 확인