기본적으로 express-rate-limit은 무분별한 요청으로 인한 서버 과부하를 막기 위해 사용되는 라이브러리이다.
백엔드 서버를 제대로 구축하여 express-rate-limit을 사용하는 것은 express-rate-limit문서에 나온 그대로 사용하면 문제없이 사용할 수 있지만 next에서 express-rate-limit을 그대로 사용하면 에러가 나고 제대로 작동하지 않기 때문에 해당 라이브러리를 사용하기 위해서는 수정하여 사용하여야 한다.
기본적인 express-rate-limit 사용 ☞ 2022.06.02 - [Javascript/Node.js] - [ Node.js ] - 서버 DDos 공격 막기
사용방법
next 환경 구축
> npx create-next-app --ts
// 위의 명령어 입력 후 enter를 계속 누른다.
tsconfig.json 의 설정은 아래와 같이 맞추어 준다.
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"incremental": true
},
"include": [
"pages/_app.tsx"
],
"exclude": [
"node_modules"
]
}
최상단 디렉토리에서 utils 폴더 생성, utils폴더안에는 주로 서비스 로직이 들어가게 된다. utils폴더 안에 rateLimit.ts 파일을 생성하여 준다. 폴더 구조는 아래와 같은 모습을 갖게 된다.
rateLimit 파일
import rateLimit from 'express-rate-limit'
import slowDown from 'express-slow-down'
const applyMiddleware = middleware => (request, response) =>
new Promise((resolve, reject) => {
middleware(request, response, result =>
result instanceof Error ? reject(result) : resolve(result)
)
})
const getIP = request =>
request.ip ||
request.headers['x-forwarded-for'] ||
request.headers['x-real-ip'] ||
request.connection.remoteAddress
// 사용자 ip를 알기 위함이다.
export const getRateLimitMiddlewares = ({
limit = 1,
windowMs = 1000,
//delayAfter = Math.round(10 / 2),
//delayMs = 500,
} = {}) => [
//slowDown({ keyGenerator: getIP, windowMs, delayAfter, delayMs }),
rateLimit({ keyGenerator: getIP, windowMs, max: limit }),
]
const middlewares = getRateLimitMiddlewares()
async function applyRateLimit(request, response) {
await Promise.all(
middlewares
.map(applyMiddleware)
.map(middleware => middleware(request, response))
)
}
export default applyRateLimit
express-slow-down
express-slow-down은 응답 속도를 늦춰주는 라이브러리이다. express-slow-down은 아직 사용법이 아리송해서 주석처리하고 express-rate-limit만 사용하였다.
getRateLimitMiddlewares
getRateLimitMiddlewares를 통해 api 제한 설정을 할 수 있다.
request.headers['x-forwarded-for']
클라이언트와 서버 중간에 트래픽이 프록시나 로드밸런서를 거치면, 서버 접근 로그에는 요청자의 원 ip가 아닌 프록시나 로드밸런서의 ip주소만을 담게 된다. 이때에 실제 요청자의 ip정보를 담고있는 헤더로 XFF 헤더라고도 한다.
마찬가지로 request.ip와 request.headers['x-real-ip'], request.connection.remoteAddress 모두 사용자의 ip를 얻기 위한 부분이다.
Promise.all()
Promise.all()은 인자값으로 배열을 주고, 해당 배열의 작업이 모두 완료되면, 순서가 보장된 결과값을 반환하여 준다.
api 파일
pages/api 폴더안에 hello.ts 파일안에 아래와 같이 작성하여 준다.
import type { NextApiRequest, NextApiResponse } from "next";
import nc from 'next-connect';
import { v4 as uuid } from 'uuid';
import rateLimit from '../../utils/rateLimit'
const handle = nc()
.get(async(req: NextApiRequest, res:NextApiResponse)=>{
await rateLimit(req, res)
const result = uuid()
return res.status(200).json(result)
})
export default handle
위의 작업까지 마친 후 > yarn dev로 실행한뒤 localhost:3000/hello 에 접속하면 uuid가 생성된 것이 나오고 계속해서 새로고침하여, 설정한 이상으로 요청하게 되면 Too may requests, please try again later. 이 나온다.
출처
express-rate-limit을 next에서 사용하기 ☞ https://kittygiraudel.com/2022/05/16/rate-limit-nextjs-api-routes/
x-forwarded-for ☞ https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Forwarded-For
'Javascript > Next.js' 카테고리의 다른 글
[ Next.js ] - 폰트 적용하는 법 (next/font) (0) | 2023.12.13 |
---|---|
[ Next.js ] - error (feat. Server Components) (0) | 2023.11.29 |
[ Next.js ] - app router란? (0) | 2023.11.19 |
[ Next.js ] - next-auth 사용법 (credentials) (2) | 2022.06.18 |