[Node.js] Express + MongoDB part#4 로그인 기능 구현

Duboo·2022년 9월 29일
0

Server + DB

목록 보기
4/6
post-thumbnail
post-custom-banner

로그인 기능을 구현하기 위해 login route 코드를 작성

app.post("/api/users/login", (req, res) => {
  // DB에서 요청한 Email 찾기
  // DB에서 요청한 Email이 있다면 비밀번호가 같은지 확인
  // 비밀 번호가 같다면 Token 생성
  // 생성된 토큰을 쿠키에 저장
})

위 로직을 코드로 해석하면 아래와 같습니다.

Index.js - /api/users/login

app.post("/api/users/login", (req, res) => {
  // DB에서 요청한 Email 찾기
  User.findOne({ email: req.body.email }, (err, user) => {
    if (!user) {
      return res.json({
        loginSuccess: false,
        message: "email을 다시 확인하세요.",
      });
    }
    // DB에서 요청한 Email이 있다면 비밀번호가 같은지 확인
    user.comparePassword(req.body.password, (err, isMatch) => {
      if (!isMatch)
        return res.json({
          loginSuccess: false,
          message: "비밀번호가 틀렸습니다",
        });
      // 비밀 번호가 같다면 Token 생성
      user.generateToken((err, user) => {
        if (err) return res.status(400).send(err);
        // 생성된 토큰을 쿠키에 저장
        res
          .cookie("hasVisited", user.token)
          .status(200)
          .json({ loginSuccess: true, userId: user._id });
      });
    });
  });
});

코드 해석
DB에서 요청한 Email 찾기
mongoDB에서 제공하는 findOne() 메소드를 사용

DB에서 요청한 Email이 있다면 비밀번호가 같은지 확인
user에 메소드를 생성해서 로직 구현

User.js

userSchema.methods.comparePassword = function (plainPassword, cb) {
  bcrypt.compare(plainPassword, this.password, function (err, isMatch) {
    if (err) return cb(err);
    cb(null, isMatch);
  });
};

DB에 생성된 비밀번호는 암호화된 비밀번호이기 때문에 비교하기 위해서는 plainPassword 또한 암호화를 해주어야합니다.

bcrypt.compare() 기능을 사용하면 plainPassword와 암호화된 비밀번호가 일치하는지 확인이 가능합니다.

user.comparePassword(req.body.password, (err, isMatch) => {
	if (!isMatch)
		return res.json({
			loginSuccess: false,
			message: "비밀번호가 틀렸습니다",
});

따라서 위와 같이 생성된 메소드를 이용해서 비밀번호를 확인하는 코드를 작성할 수 있습니다.

비밀 번호가 같다면 Token 생성
user에 메소드를 생성하고 jwt 모듈을 사용해서 로직 구현

npm i jsonwebtoken
jsonwebtoken

User.js

const jwt = require("jsonwebtoken");

userSchema.methods.generateToken = function (cb) {
  var user = this;
  // jsonwebtoken을 사용해서 토큰 생성
  var token = jwt.sign(user._id.toHexString(), "createToken");

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

var user = this;로 user를 가져옴

var token = jwt.sign(user._id.toHexString(), "createToken");
jwt.sign()은 DB에 들어있는 _id"createToken"를 합쳐서 새로운 토큰을 생성해줍니다.

  • user._id.toHexString() : 인자로 넘겨주는 값은 plain object여야 하기 때문에 .toHexString() 사용

이렇게 만들어진 토큰을 user.token = token으로 먼저 만들어준 스키마 토큰 값에 넣어주고 저장합니다.

const cookieParser = require("cookie-parser");
app.use(cookieParser());

.
.
.

user.generateToken((err, user) => {
	if (err) return res.status(400).send(err);
		// 생성된 토큰을 쿠키에 저장
![](https://velog.velcdn.com/images/duboo/post/73badb58-0f56-40aa-a749-885106f27930/image.png)
![](https://velog.velcdn.com/images/duboo/post/87a50bbd-fea6-469b-9c8b-ede8e4809319/image.png)
		res
		.cookie("hasVisited", user.token)
		.status(200)
		.json({ loginSuccess: true, userId: user._id });
});

생성된 토큰의 저장은 쿠키, 로컬스토리지 등 클라이언트 저장소에 저장합니다.

쿠키에 토큰을 저장하기 위해서 cookie-parser 모듈 설치

npm i cookie-parser
cookie-parser


Postman과 MongoDB를 사용해서 로그인이 되는지 확인

PostmanMongoDB
profile
둡둡
post-custom-banner

0개의 댓글