1. 사용량 제한 구현과 이유
DOS 공격 등을 대비해야 함 -> 새로고침을 계속하면서 공격하는 것 (무차별 요청)
- 일정 시간동안 횟수 제한을 두어 무차별적인 요청을 막을 필요가 있음
- npm i express-rate-limit
- apiLimiter 미들웨어 추가
- windowMS(기준 시간), max(허용 횟수), delayMS(호출 간격), handler(제한 초과 시 콜백 함수)
- deprecated 미들웨어는 사용하면 안 되는 라우터에 붙여서 사용 시 경고
const jwt = require('jsonwebtoken');
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next();
} else {
res.status(403).send('로그인 필요');
}
};
exports.isNotLoggedIn = (req, res, next) => {
if (!req.isAuthenticated()) {
next();
} else {
res.redirect('/');
}
};
exports.verifyToken = (req, res, next) => {
try {
req.decoded = jwt.verify(req.headers.authorization, process.env.JWT_SECRET);
return next();
} catch (error) {
if (error.name === 'TokenExpiredError') { // 유효기간 초과
return res.status(419).json({
code: 419,
message: '토큰이 만료되었습니다',
});
}
return res.status(401).json({
code: 401,
message: '유효하지 않은 토큰입니다',
});
}
};
2. 응답 코드 정리
응답 코드를 정리해서 어떤 에러가 발생했는지 알려주기
- 일관성이 있으면 됨
3. 새 라우터 버전 내놓기
사용량 제한 기능이 추가되어 기존 API와 호환되지 않음
- 이런 경우 새로운 버전의 라우터를 내놓으면 됨
- v2 라우터 작성(apiLimiter 추가됨)
- v1 라우터는 deprecated 처리(router.use로 한 번에 모든 라우터에 적용)
nodecat의 버전 v2로 바꾸기
const express = require('express');
const jwt = require('jsonwebtoken');
const { verifyToken, apiLimiter } = require('./middlewares');
const { Domain, User, Post, Hashtag } = require('../models');
const router = express.Router();
router.post('/token', apiLimiter, async (req, res) => {
const { clientSecret } = req.body;
try {
const domain = await Domain.findOne({
where: { clientSecret },
include: {
model: User,
attribute: ['nick', 'id'],
},
});
if (!domain) {
return res.status(401).json({
code: 401,
message: '등록되지 않은 도메인입니다. 먼저 도메인을 등록하세요',
});
}
const token = jwt.sign({
id: domain.User.id,
nick: domain.User.nick,
}, process.env.JWT_SECRET, {
expiresIn: '30m', // 30분
issuer: 'nodebird',
});
return res.json({
code: 200,
message: '토큰이 발급되었습니다',
token,
});
} catch (error) {
console.error(error);
return res.status(500).json({
code: 500,
message: '서버 에러',
});
}
});
router.get('/test', verifyToken, apiLimiter, (req, res) => {
res.json(req.decoded);
});
router.get('/posts/my', apiLimiter, verifyToken, (req, res) => {
Post.findAll({ where: { userId: req.decoded.id } })
.then((posts) => {
console.log(posts);
res.json({
code: 200,
payload: posts,
});
})
.catch((error) => {
console.error(error);
return res.status(500).json({
code: 500,
message: '서버 에러',
});
});
});
router.get('/posts/hashtag/:title', verifyToken, apiLimiter, async (req, res) => {
try {
const hashtag = await Hashtag.findOne({ where: { title: req.params.title } });
if (!hashtag) {
return res.status(404).json({
code: 404,
message: '검색 결과가 없습니다',
});
}
const posts = await hashtag.getPosts();
return res.json({
code: 200,
payload: posts,
});
} catch (error) {
console.error(error);
return res.status(500).json({
code: 500,
message: '서버 에러',
});
}
});
module.exports = router;
v1 API를 사용하거나 사용량을 초과하면 에러 발생
'Node.js' 카테고리의 다른 글
Nodejs Test하는 이유와 Jest (0) | 2021.01.12 |
---|---|
CORS 에러 이해하기 (0) | 2021.01.11 |
Nodejs 호출 서버 만들기 (0) | 2021.01.10 |
Node에서 API 서버 만들기 (0) | 2021.01.08 |
multer 사용해서 이미지 업로드 구현 (0) | 2021.01.06 |