Nodejs: Signing up and signing in with a refresh token and an access token
2023. 11. 22. 23:34ㆍJavascript Node.js
Main video
Code
// ./routes/auth.router.js
import { Router } from "express";
import bcrypt from "bcrypt";
import db from "../models/index.js";
import jwt from "jsonwebtoken";
import {
PASSWORD_SALT_ROUNDS,
JWT_ACCESS_TOKEN_SECRET,
JWT_REFRESH_TOKEN_SECRET,
JWT_ACCESS_TOKEN_EXPIRES_IN,
JWT_REFRESH_TOKEN_EXPIRES_IN,
} from "../constants/security.constant.js";
const { User } = db;
const authRouter = Router();
// 생년월일(정규식)
const datePattern = /^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
// 회원가입 /api/auth/signup
authRouter.post("/signup", async (req, res, next) => {
try {
const { email, name, myIntro, password, passwordConfirm, birth } = req.body;
// 이메일 정보가 없는 경우
if (!email) {
return res.status(400).json({
ok: false,
message: "이메일 입력이 필요합니다.",
});
}
// 이름을 작성하지 않았을 경우
if (!name) {
return res.status(400).json({
ok: false,
message: "이름 입력이 필요합니다.",
});
}
// 생년월일을 입력하지 않았을 경우
if (!birth) {
return res.status(400).json({
ok: false,
message: "생년월일 입력이 필요합니다.",
});
}
// 생년월일을 잘못된 형식으로 작성했을 경우(정규식 사용)
if (!datePattern.test(birth)) {
return res.status(400).json({
ok: false,
message: "생년월일을 잘못 입력하셨습니다.",
});
}
// 비밀번호가 없었을 경우
if (!password) {
return res.status(400).json({
ok: false,
message: "비밀번호 입력이 필요합니다.",
});
}
// 패스워드 확인란을 작성하지 않았을 경우
if (!passwordConfirm) {
return res.status(400).json({
ok: false,
message: "비밀번호 확인 입력이 필요합니다.",
});
}
// 패스워드가 서로 일치하지 않았을 경우
if (password !== passwordConfirm) {
return res.status(400).json({
ok: false,
message: "입력한 비밀번호가 서로 일치하지 않습니다.",
});
}
// 비밀번호의 형식: 최소 7자 이상 작성
if (password.length < 7) {
return res.status(400).json({
ok: false,
message: "비밀번호는 최소 7자리 이상입니다.",
});
}
// 이메일에 알맞은 형식 규정
let emailValidationRegex = new RegExp("[a-z0-9._]+@[a-z]+.[a-z]{2,3}");
const isValidEmail = emailValidationRegex.test(email);
// 이메일 형식이 잘못되었을 경우
if (!isValidEmail) {
return res.status(400).json({
ok: false,
message: "올바른 이메일 형식이 아닙니다.",
});
}
// 이미 가입된 유저를 찾을 때
const existedUser = await User.findOne({ where: { email } });
// 가입된 유저가 있을 경우
if (existedUser) {
return res.status(409).json({
ok: false,
message: "이미 가입된 이메일입니다.",
});
}
// 비밀번호 hash화
const hashedPassword = bcrypt.hashSync(password, PASSWORD_SALT_ROUNDS);
// 유저 회원가입 성공
const newUser = (
await User.create({ email, name, birth, myIntro, password: hashedPassword })
).toJSON();
delete newUser.password;
return res.status(201).json({
ok: true,
message: "회원가입에 성공하였습니다.",
data: newUser,
});
} catch (error) {
next(error);
}
});
// 로그인/api/auth/signin
authRouter.post("/signin", async (req, res, next) => {
try {
//로그인시 req.body에서 값을 서버에 요청
const { email, password } = req.body;
// 이메일을 작성하지 않았을 경우
if (!email) {
return res.status(400).json({
ok: false,
message: "이메일 입력이 필요합니다.",
});
}
// 비밀번호를 작성하지 않았을 경우
if (!password) {
return res.status(400).json({
ok: false,
message: "비밀번호 입력이 필요합니다.",
});
}
// 로그인 요청시 해당 유저가 있는지 확인
const user = (await User.findOne({ where: { email } }))?.toJSON();
// 유가가 있을시 비밀번호
const hashedPassword = user?.password;
// hash화된 회원가입시 비밀번호화 로그인 비밀번호화 비교
const isPasswordMatched = bcrypt.compareSync(password, hashedPassword);
// 회원가입된 유저와 비밀번호가 확인된 유저
const isCorrectUser = user && isPasswordMatched;
// 회원가입, 즉 가입된 유저 정보가 없는 경우
if (!isCorrectUser) {
return res.status(400).json({
ok: false,
message: "일치하는 인증 정보가 없습니다.",
});
}
// JWT ACCESS TOKEN: 로그인시 서버측에서 사용자에게 제공
const accessToken = jwt.sign({ userId: user.id }, JWT_ACCESS_TOKEN_SECRET, {
expiresIn: JWT_ACCESS_TOKEN_EXPIRES_IN,
});
// JWT REFRESH TOKEN: 로그인시 서버측에서 사용자에게 제공
// 이 토큰은 JWT ACCESS TOKEN이 만료되었을 경우 대체 인증 수단으로 사용
const refreshToken = jwt.sign({ userId: user.id }, JWT_REFRESH_TOKEN_SECRET, {
expiresIn: JWT_REFRESH_TOKEN_EXPIRES_IN,
});
// 로그인에 성공했을 경우
return res.status(200).json({
ok: true,
message: "로그인에 성공하였습니다.",
data: { accessToken, refreshToken },
});
} catch (error) {
next(error);
}
});
export { authRouter };
'Javascript Node.js' 카테고리의 다른 글
Javascript: Optional chaing (?.) (0) | 2023.12.11 |
---|---|
Project: present a web page about the blog. (0) | 2023.12.08 |
How to use Access Token and Refresh Token? (0) | 2023.11.27 |
Nodejs: Signin, Login, User Information (1) | 2023.11.22 |
Nodejs: The order of web development (0) | 2023.11.20 |