1)게시글 전체조회 및 상세조회
// 게시글 전체조회
router.get("/posts", async (req, res) => {
const showPost = await Posts.findAll({
attributes: ["postId", "userId", "title", "nickname", "createdAt", "updatedAt"],
order: [["createdAt", "DESC"]],
});
try {
if (!showPost.length) {
return res.status(404).json({ message: "게시글이 없습니다." });
}
res.status(200).json({
showPost: showPost,
});
} catch (err) {
res.status(400).json({
message: "게시글 조회에 실패하였습니다.",
});
}
});
기존에는 map()
메서드로 출력할 목록들을 따로 만들어서 작동했는데 find()
메서드의 attributes속성을 이용하여 코드 수정
게시글 수정/삭제
//게시글 수정
router.put("/posts/:postId", authMiddleware, async (req, res) => {
const { postId } = req.params;
const { userId } = res.locals.user;
const { title, content } = req.body;
try {
const modifyPost = await Posts.findOne({ where: { postId } });
if (!modifyPost) {
return res.status(404).json({ message: "해당 게시글을 찾을 수 없습니다." });
} else if (!title || !content) {
return res.status(400).json({ message: "데이터를 입력해주세요." });
} else if (modifyPost.UserId !== userId) {
return res.status(401).json({ message: "수정권한이 없습니다." });
} else {
await Posts.update(
{ title, content },
{ where: { [Op.and]: [{ postId }, { UserId: userId }] } }
);
res.status(201).json({
message: "게시글 수정 완료",
Detail: {
title: modifyPost.title,
content: modifyPost.content,
updatedAt: modifyPost.updatedAt,
},
});
}
} catch (err) {
res.status(400).json({
message: "게시글 수정에 실패하였습니다.",
});
}
});
userId를 비교하여 현재 로그인 한 아이디가 아니라면 수정 또는 삭제 권한이 없게하고 일치하는 유저만 가능하게 구현
회원가입
// 회원가입
router.post("/signup", async (req, res) => {
const { email, nickname, password, confirmPassword } = req.body;
const savedUsers = await Users.findOne({
where: {
[Op.or]: [{ email }, { nickname }],
},
});
let regExp = /[ \{\}\[\]\/?.,;:|\)*~`!^\-_+┼<>@\#$%&\'\"\\\(\=]/;
console.log(savedUsers);
try {
if (nickname.length <= 3 || regExp.test(nickname)) {
res.status(412).json({
message: "닉네임은 최소 3자 이상이여야 하며, 특수문자 및 공백을 사용할 수 없습니다.",
});
return;
} else if (password.length <= 4 || password === nickname) {
res.status(412).json({
message: "비밀번호는 최소 4자 이상이여야 하며, 닉네임과 같은 값이 포함될 수 없습니다.",
});
return;
}
if (password !== confirmPassword) {
res.status(412).json({
message: "입력한 비밀번호와 비밀번호 확인값이 일치하지 않습니다.",
});
return;
}
if (savedUsers) {
res.status(412).json({
message: "이메일 또는 닉네임이 이미 사용중입니다.",
});
return;
}
const user = await Users.create({ email, nickname, password });
return res.status(201).json({
message: "회원가입이 완료되었습니다.",
});
} catch (err) {
res.status(400).json({
message: "요청한 데이터 형식이 올바르지 않습니다.",
});
}
});
회원가입에 대한 예외처리를 작성(닉네임 특수문자 사용불가, 길이수 제한 등)하고 회원가입 완료 시 유저의 email, nickname, password 정보를 DB에 저장
로그인
// 로그인 API
router.post("/login", async (req, res) => {
const { email, password } = req.body;
const user = await Users.findOne({ where: { email } });
try {
if (!user || password !== user.password) {
res.status(400).json({
errorMessage: "이메일 또는 패스워드가 틀렸습니다.",
});
return;
}
const token = jwt.sign({ userId: user.userId }, "customized-secret-key", { expiresIn: "30m" });
res.cookie("authorization", `Bearer ${token}`);
res.status(200).json({
token,
message: "로그인에 성공하였습니다.",
});
} catch (err) {
res.status(400).json({
message: "로그인에 실패하였습니다.",
});
}
});
DB에 있는 유저정보와 비교, 로그인에 성공하였다면 토큰을 발행하고 토큰의 만료기간은 30분으로 설정
API명세서와 README 작성 후 제출하면 이번 과제도 끝날 것 같다. 코드리뷰를 꼼꼼히 하고 Node 강의를 다시 복습해볼 예정이다.