유효성검사
valid action
사용자가 입력한 값의 유효성(=타당성)을 확인하는 것
ex
- user_id: body에 값이 있어야한다, 숫자
- name: body에 값이 있어야한다, 문자열
외부모듈 express-validator
https://www.npmjs.com/package/express-validator
express-validator
Express middleware for the validator module.. Latest version: 7.0.1, last published: 8 months ago. Start using express-validator in your project by running `npm i express-validator`. There are 10052 other projects in the npm registry using express-validato
www.npmjs.com
유효성 검사 사용하기
const { body, validationResult } = require("express-validator");
- validationResult : 문제여부
const err = validationResult(req);
- err는 배열 형식으로 넘어온다. err.isEmpty()가 참이라면 문제가 없는 것
유효성 검사 err 확인하기
1. 공통함수를 만들어서 사용해주기
function validate(req, res) {
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
콜백함수의 해당 부분에서 호출해주면 잘 수행된다.
2. 미들웨어로 만들어주기,
const validate = (req, res, next) => {
const err = validationResult(req);
if (err.isEmpty()) {
return next();
} else {
return res.status(400).json(err.array());
}
};
리스폰스로 해결하려나보다! 로 인식할 수 있다. 다음 콜백함수로 넘어가야한다는 것을 알려줘야한다.
next를 이용한다.
미들웨어를 콜백함수 호출 전 검사하는 부분에서 불러온다.
ex
.get(
[
body("user_id")
.notEmpty()
.isInt()
.withMessage("user_id는 숫자여야합니다."),
validate,
],
(req, res) => {
//회원의 채널 조회
const err = validationResult(req);
if (!err.isEmpty()) {
return res.status(400).json(err.array());
}
let { user_id } = req.body;
sql = `SELECT * FROM channels WHERE user_id = ?`;
conn.query(sql, user_id, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.length) {
res.status(200).json(results);
} else {
res.status(404).json({
message: "해당 id의 회원의 채널이 없습니다.",
});
}
});
}
)
참고 1
- .isEmail() : email인지 검사
- .isStrongPassword()
참고 - 미들웨어란?
- 미들웨어 함수는 req객체, res객체, 그리고 어플리케이션 요청-응답 사이클 도중 그 다음의 미들웨어 함수에 대한 엑세스 권한을 갖는 함수이다. 즉, 요청 전에 처리할 수 있는 어떤 것이다.
- next를 통해 미들웨어는 순차적으로 처리된다.
- 따라서 유효성 검사를 할 때, 미들웨어인 validate에서 next를 해주지 않으면 err.isEmpty()인 경우, 즉 유효성 검사를 통과한 경우에는 핸들러로 넘어가지 않는다.
const validate = (req, res, next) => {
const err = validationResult(req);
if (err.isEmpty()) {
} else {
return res.status(400).json(err.array());
}
};
users.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
const validate = (req, res, next) => {
const err = validationResult(req);
if (err.isEmpty()) {
return next();
} else {
return res.status(400).json(err.array());
}
};
router
.route("/users")
.get(
[
body("email").notEmpty().isEmail().withMessage("user_id 확인 필요"),
validate,
],
(req, res) => {
//회원 개별 조회
let { email } = req.body;
sql = `SELECT * FROM users WHERE email = ?`;
conn.query(sql, email, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.length) {
res.status(200).json(results);
} else {
//해당id의 회원이 없는 경우
res.status(404).json(results);
}
});
}
)
.delete(
[
body("email").notEmpty().isEmail().withMessage("email 확인 필요"),
validate,
],
(req, res) => {
//회원 탈퇴
let { email } = req.body;
let sql = `DELETE FROM users WHERE email = ?`;
conn.query(sql, email, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.affectedRows) {
res.status(200).json(results);
} else {
//해당 id의 회원이 없는 경우
res.status(404).json(results);
}
});
}
);
///로그인
router.post(
"/login",
[
body("email").notEmpty().isEmail().withMessage("email must be a string."),
body("pw").notEmpty().isString().withMessage("pw must be a string"),
validate,
],
(req, res) => {
let { email, pw } = req.body;
let sql = `SELECT * FROM users WHERE email = ? `;
conn.query(sql, email, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
let loginUser = results[0];
if (loginUser && loginUser.pw == pw) {
res.status(200).json({ message: `${loginUser.name}님 환영합니다.` });
} else {
res.status(404).json({
message: "id 및 pw를 확인해주세요.",
});
}
});
}
);
//회원가입
router.post(
"/join",
[
body("email").notEmpty().isEmail().withMessage("email 확인 필요"),
body("pw").notEmpty().isString().withMessage("pw확인 필요"),
body("name").notEmpty().isString().withMessage("name확인 필요"),
validate,
],
(req, res) => {
let { email, pw, name } = req.body;
let sql = `INSERT INTO users (email,name,pw) VALUES (?,?,?)`;
let values = [email, name, pw];
conn.query(sql, values, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
res.status(200).json(results);
});
}
);
module.exports = router;
channels.js
const express = require("express");
const router = express.Router();
const conn = require("../mariadb");
const { body, param, validationResult } = require("express-validator");
router.use(express.json());
//변수에 담아보기 - 하나의 미들웨어 역할
const validate = (req, res, next) => {
const err = validationResult(req);
if (err.isEmpty()) {
return next();
} else {
return res.status(400).json(err.array());
}
};
router
.route("/")
.post(
[
body("user_id")
.notEmpty()
.isInt()
.withMessage("user_id must be a number."),
body("channelName")
.notEmpty()
.isString()
.withMessage("name must be a letter"),
body("description")
.notEmpty()
.withMessage("Channel description is required."),
validate,
],
(req, res) => {
// 채널 생성
const { user_id, channelName, description } = req.body; // 수정: 변수를 선언해야 합니다.
let sql =
"INSERT INTO channels (channelName, description, user_id) VALUES (?, ?, ?)";
const values = [channelName, description, user_id]; // 수정: 변수명이 정확해야 합니다.
conn.query(sql, values, function (err, results) {
if (!err) {
res.status(201).json(results);
} else {
//채널을 생성하지 못함.
return res.status(400).send();
}
});
}
)
.get(
[
body("user_id")
.notEmpty()
.isInt()
.withMessage("user_id는 숫자여야합니다."),
validate,
],
(req, res) => {
//회원의 채널 조회
let { user_id } = req.body;
sql = `SELECT * FROM channels WHERE user_id = ?`;
conn.query(sql, user_id, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.length) {
res.status(200).json(results);
} else {
//해당id의 회원의 채널이 없는 경우
res.status(404).json(results);
}
});
}
);
router
.route("/:id")
.put(
[
param("id").notEmpty().withMessage("채널 id 필요"),
body("channelName").notEmpty().isString().withMessage("채널명 필요"),
body("description").notEmpty().isString().withMessage("채널 설명 필요"),
validate,
],
(req, res) => {
//채널 수정
let { id } = req.params;
id = parseInt(id);
let { channelName, description } = req.body;
let sql = `UPDATE channels SET channelName=?, description=? WHERE id=?`;
let values = [channelName, description, id];
conn.query(sql, values, function (err, results) {
if (err) {
return res.status(400).json({ err });
}
if (results.affectedRows) {
res.status(200).json(results);
} else {
//해당 id의 채널이 없는 경우
res.status(400).json(results);
}
});
}
)
.delete(
[param("id").notEmpty().withMessage("채널 id 필요"), validate],
(req, res) => {
//채널 삭제
let { id } = req.params;
id = parseInt(id);
let sql = `DELETE FROM channels WHERE id = ?`;
conn.query(sql, id, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.affectedRows) {
res.status(200).json(results);
} else {
//해당 id의 채널이 없는 경우
res.status(404).json(results);
}
});
}
)
.get(
[param("id").notEmpty().withMessage("채널 id 필요").notEmpty(), validate],
(req, res) => {
//개별 채널 조회
let { id } = req.params;
sql = `SELECT * FROM channels WHERE id = ?`;
conn.query(sql, id, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
if (results.length) {
res.status(200).json(results);
} else {
//해당 id의 채널이 없는 경우
res.status(404).json(results);
}
});
}
);
module.exports = router;
app.js
const express = require("express");
const app = express();
app.listen(3000);
const userRouter = require("./routes/users");
const channelRouter = require("./routes/channels");
app.use("/", userRouter);
app.use("/channels", channelRouter);
'타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) > TIL' 카테고리의 다른 글
웹풀사이클 25일차 - (0) | 2023.12.30 |
---|---|
웹풀사이클 24일차 - 인증과 인가 (2) | 2023.12.27 |
웹풀사이클 22일차 - workbench로 유튜브 채널, user (0) | 2023.12.23 |
웹 풀사이클 21일차 - MARIADB로 게시판 만들기 (0) | 2023.12.22 |
웹풀사이클 20일차 - RDBMS, 연관관계 (0) | 2023.12.20 |