프로그래머스 데브코스, 국비지원교육, 코딩부트캠프
어제 하다가 끝내지 못한 UserController.js를 완성시켰다. 로그인 기능과 비밀번호 초기화 요청, 비밀번호 초기화가 있다. 생각해보니 로그아웃 기능이 없는데 이건 내가 따로 만들어 봐야겠다. 사실 지금도 강의랑은 좀 다르게 짜고 있지만
const signin = (req, res) => {
const { email, password } = req.body;
const sql = 'select * from users where email = ?';
conn.query(sql, email, (err, results) => {
if (err) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: '서버 에러',
});
}
const signinUser = results[0];
if (!signinUser) {
return res.status(StatusCodes.UNAUTHORIZED).json({
message: '해당하는 이메일이 존재하지 않습니다.',
});
}
try {
const hashedPassword = crypto.pbkdf2Sync(password, signinUser.salt, 10000, 10, 'sha512').toString('base64');
if (hashedPassword === signinUser.password) {
const token = jwt.sign(
{
email: signinUser.email,
},
process.env.PRIVATE_KEY,
{
expiresIn: '1h',
issuer: 'minkyung',
}
);
res.cookie('token', token, {
httpOnly: true,
secure: true,
sameSite: 'none',
});
return res.status(StatusCodes.OK).json({
message: '로그인 성공',
token: token,
});
} else {
return res.status(StatusCodes.UNAUTHORIZED).json({
message: '비밀번호가 일치하지 않습니다.',
});
}
} catch (err) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: '비밀번호 해싱 중 문제가 발생하였습니다.',
});
}
});
};
비동기로 코드를 짠다면 좀 더 보기 좋아질 것 같은데 내가 아직 비동기 부분에 대해서 좀 미숙한지라... 조금 더 공부한 후 전체적으로 리팩토링을 할 예정이다.
Unauthorized
반환Unauthorized
반환에러 정상 반환
로그인 성공 시 토큰 정상 반환
위 경우는 솔트값이 포함되지 않은 계정으로 로그인 시 발생하는 에러
const pwdResetRequest = (req, res) => {
const { email } = req.body;
const sql = 'select * from users where email = ?';
conn.query(sql, email, (err, results) => {
if (err) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: '서버 에러',
});
}
const user = results[0];
if (!user) {
return res.status(StatusCodes.UNAUTHORIZED).json({
message: '해당하는 이메일이 존재하지 않습니다.',
});
} else {
return res.status(StatusCodes.OK).json({
message: '이메일 발송 성공',
email: email,
});
}
});
};
const pwdReset = (req, res) => {
const { email, password } = req.body;
const salt = crypto.randomBytes(10).toString('base64');
const hashPwd = crypto.pbkdf2Sync(password, salt, 10000, 10, 'sha512').toString('base64');
const sqlUpdate = 'update users set password = ?, salt = ? where email = ?';
const sqlSelect = 'select * from users where email = ?';
const values = [hashPwd, salt, email];
conn.query(sqlSelect, email, (err, results) => {
if (err) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: '서버 에러',
});
}
const user = results[0];
if (!user) {
return res.status(StatusCodes.UNAUTHORIZED).json({
message: '해당하는 이메일이 존재하지 않습니다.',
});
}
const hashedNewPassword = crypto.pbkdf2Sync(password, user.salt, 10000, 10, 'sha512').toString('base64');
if (hashedNewPassword === user.password) {
return res.status(StatusCodes.BAD_REQUEST).json({
message: '새 비밀번호는 기존 비밀번호와 달라야 합니다.',
});
}
conn.query(sqlUpdate, values, (err, results) => {
if (err) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: '서버 에러',
});
}
if (results.affectedRows > 0) {
res.status(StatusCodes.OK).json({
message: '비밀번호 초기화 성공',
});
} else {
res.status(StatusCodes.BAD_REQUEST).json({
message: '비밀번호 초기화 실패',
});
}
});
});
};
마찬가지로 비동기를 사용하지 않아 코드가 조금 지저분...하다. 빨리 공부해서 리팩토링해야지😭
nodemailer
를 이용해서 차후 추가할 예정, 지금은 우선 메일이 맞는지만 확인이메일 존재 시 해당 이메일 주소 반환
이메일 존재하지 않으면 Unathorized
반환
새로운 비밀번호 초기화에 성공한다면
이게 기존 비밀번호 (해시화되어 저장)
변경 후 다시 조회하면 비밀번호와 솔트값 모두 바뀌어있다.
변경 이후 변경된 비밀번호로 로그인 시 정상적으로 로그인이 되는 걸 확인할 수 있다.
기존 비밀번호와 똑같은 비밀번호를 입력 후 수정하려고 하면 Bad request
를 반환한다.