Skip to content

Commit 6cf6ff7

Browse files
committed
fix: adds rate limit
1 parent 26b0bef commit 6cf6ff7

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/server/CacheManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Redis from 'ioredis';
22
import checkCacheRule from './checkCacheRule';
33

4-
const redis = new Redis({
4+
export const redis = new Redis({
55
host: process.env.REACT_APP_REDIS_HOST || 'localhost',
66
});
77

src/server/rateLimitMiddleware.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Middleware } from 'koa';
2+
import { redis } from './CacheManager';
3+
4+
const rateLimitMiddleware: Middleware = async (ctx, next) => {
5+
const ip = ctx.request.ips.slice(-1)[0] || ctx.request.ip;
6+
7+
const key = `${ip}:pageview`;
8+
const blockedKey = `${ip}:blocked`;
9+
10+
const blocked = await redis.get(blockedKey);
11+
12+
if (blocked) {
13+
ctx.status = 429;
14+
ctx.body = { msg: 'Too many request' };
15+
return;
16+
}
17+
const exists = await redis.get(key);
18+
19+
if (typeof exists === 'number' && exists > 100) {
20+
await redis.set(blockedKey, 1);
21+
await redis.expire(blockedKey, 300);
22+
ctx.status = 429;
23+
ctx.body = { msg: 'Too many request' };
24+
return;
25+
}
26+
27+
if (exists === null) {
28+
await redis.set(key, 1);
29+
await redis.expire(key, 60);
30+
} else {
31+
console.log(`${ip} - ${exists}`);
32+
await redis.incr(key);
33+
}
34+
return next();
35+
};
36+
37+
export default rateLimitMiddleware;

0 commit comments

Comments
 (0)