이메일 인증 기능 구현을 완료하고 회원가입 기능을 완료했다.
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
를 각각의 변수로
객체 디스트럭처링을 이용하여 담아주었다.
password
는 const
가 아닌 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
를 이용하여 데이터를 저장한다.
로그인 기능을 만들기 전에 토큰을 생성하는 함수를 먼저 만들어주었다.
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
를 이용하여 검증을
진행했다.
토큰을 생성할 때처럼 토큰과 시크릿이 필요하다.
만약 토큰이 복호화가 되지않는다면 쿠키 자체를 지워주고
복호화가 정상적으로 진행된다면 req
에 userInfo
라는 새로운 속성을 추가해 next
로 넘겨준다.
export const signOut = (req, res) => {
res.clearCookie("token");
// Todo : 클라이언트 만들 때 로그인 페이지로 리다이렉트 걸기
res.redirect("signIN Page Url");
};