Jake's Board - Side Project

이재익·2019년 12월 1일
0

Jake's Board

목록 보기
2/2

1. 회원가입 하기

이메일 인증 기능 구현을 완료하고 회원가입 기능을 완료했다.

import bcryptjs from "bcryptjs";

export const signUp = (req, res) => {
  const {
    email,
    nickName,
    provider = "local",
    // Todo : 기본 imgUrl 교체하기
    profileImg = "imgUrl"
  } = req.body;
  let { password } = req.body;
};

우선 Request의 body에 담겨 있는 email, nickName, provider, profileImg를 각각의 변수로
객체 디스트럭처링을 이용하여 담아주었다.

passwordconst가 아닌 let으로 따로 빼둔 이유는 bcryptjs를 이용하여 비밀번호를
암호화시켜 저장하기 위해서다.

bcryptjs.genSalt(10, (_, salt) => {
    bcryptjs.hash(password, salt, (_, hash) => {
      password = hash;

      User.create({ email, nickName, password, provider, profileImg })
        .then(_ => {
          res.status(201);
          res.send(true);
        })
        .catch(err => {
          res.status(500);
          res.send(err);
        });
    });
  });

먼저 genSalt 메소드를 이용하여 salt 값을 생성 후 hash 메소드를 이용하여 비밀번호 암호화를 진행하였다.

암호화가 완료되면 User 테이블에 email, nickName, password, provider, profileImg
sequelize를 이용하여 데이터를 저장한다.

2. 로그인

토큰 생성

로그인 기능을 만들기 전에 토큰을 생성하는 함수를 먼저 만들어주었다.

import jwt from "jsonwebtoken";
const { tokenSecret } = process.env;

export const createJWT = userInfo => {
  const token = jwt.sign(userInfo, tokenSecret, {
    expiresIn: "10h",
    subject: "userInfo"
  });

  return token;
};

userInfo 객체를 arguments로 전달 받아 토큰을 생성하는 함수이고 jsonwebtoken 모듈을 이용하여 기능을 구현하였다.

전달받은 arguments를 payload 그리고 env 파일에 작성해둔 tokenSecret 과 옵션 설정 후 sign 메소드로
토큰을 생성해주고 그 토큰 자체를 반환하는 함수를 구현하였다.

로그인

export const signIn = (req, res) => {
  const { email, password } = req.body;

  User.findOne({ where: { email } })
    .then(userData => {
      bcryptjs.compare(password, userData.password, (err, result) => {
        if (result) {
          const token = createJWT({ email, password });

          res.cookie("token", token, {
            httpOnly: true,
            expires: new Date(Date.now() + 60 * 60 * 1000 * 24 * 7),
            signed: true
          });
          res.status(201);
          res.send(true);
        } else {
          res.status(400);
          res.send("Wrong password");
        }
      });
    })
    .catch(err => {
      res.status(500);
      res.send(err);
    });
};

User 테이블에서 where 조건으로 email이 req의 email과 같은 데이터를 찾아 주었고,
bcryptjs의 메소드인 compare를 이용하여 해싱된 패스워드와 입력받은 패스워드가 일치하는지 검사를 진행했다.

그리고 만약 일치한다면 토큰을 생성해준 뒤 쿠키에 토큰을 담아주는 방법을 이용했다.

토큰 검증

export const verifyJWT = (req, res, next) => {
  const { token } = req.signedCookies;

  jwt.verify(token, tokenSecret, (err, decoded) => {
    if (err) {
      res.clearCookie("token");
      res.status(401);
      res.send("token expire");
    } else {
      req.userInfo = decoded;
      next();
    }
  });
};

우선 req에 있는 쿠키에서 토큰을 변수에 담아주고 그 토큰을 jwt의 메소드인 verify를 이용하여 검증을
진행했다.

토큰을 생성할 때처럼 토큰과 시크릿이 필요하다.
만약 토큰이 복호화가 되지않는다면 쿠키 자체를 지워주고
복호화가 정상적으로 진행된다면 requserInfo라는 새로운 속성을 추가해 next로 넘겨준다.

로그아웃

export const signOut = (req, res) => {
  res.clearCookie("token");
  // Todo : 클라이언트 만들 때 로그인 페이지로 리다이렉트 걸기
  res.redirect("signIN Page Url");
};
profile
열정 있는 개발자

0개의 댓글