DevToolbox
Menu
Accueil
CSS / Styling
Design System GeneratorColor Palette GeneratorNewTailwind Class SorterNewSVG Optimizer & ViewerNewBreakpoint VisualizerNewCSS Unit ConverterNew
Backend
Prisma Schema → MCDJSON → TypeScriptNewSQL FormatterNewRegex Tester & ExplainerNewCron Expression BuilderNewENV File ValidatorNewChmod CalculatorNew
Cybersécurité
Hash GeneratorNewJWT DecoderNewPassword AnalyzerNewCSP Header BuilderNewRate Limiter GeneratorNewEncoder / DecoderNewSecurity Headers CheckerNewCORS Header BuilderNewSSL Certificate InspectorNew
Utilitaires Dev
UUID/ULID GeneratorNewTimestamp ConverterNewHTTP Status CodesNewDiff ViewerNewMarkdown PreviewNewLorem Ipsum GeneratorNewBase ConverterNewJSON FormatterNewIcon Libraries ComparatorNew

DevToolbox - Built with Next.js and shadcn/ui.

À proposGitHub

Rate Limiter Generator

Générez du code de rate limiting pour Node.js, Python et Go

Configuration

Lissage du trafic avec remplissage progressif de jetons

Résumé
100 req / 60 secondesToken BucketNode.js (TypeScript)

Code généré

1import { Redis } from "ioredis";
2
3const redis = new Redis();
4
5interface TokenBucketResult {
6 allowed: boolean;
7 remaining: number;
8 retryAfter: number | null;
9}
10
11/**
12 * Token Bucket Rate Limiter
13 * Max: 100 requêtes par 1min
14 */
15export async function tokenBucket(key: string): Promise<TokenBucketResult> {
16 const bucketKey = `rate-limit:${key}`;
17 const maxTokens = 100;
18 const refillRate = maxTokens / (60000 / 1000); // tokens per second
19 const now = Date.now();
20
21 const lua = `
22 local key = KEYS[1]
23 local maxTokens = tonumber(ARGV[1])
24 local refillRate = tonumber(ARGV[2])
25 local now = tonumber(ARGV[3])
26
27 local bucket = redis.call('HMGET', key, 'tokens', 'lastRefill')
28 local tokens = tonumber(bucket[1]) or maxTokens
29 local lastRefill = tonumber(bucket[2]) or now
30
31 local elapsed = (now - lastRefill) / 1000
32 tokens = math.min(maxTokens, tokens + elapsed * refillRate)
33
34 if tokens >= 1 then
35 tokens = tokens - 1
36 redis.call('HMSET', key, 'tokens', tokens, 'lastRefill', now)
37 redis.call('PEXPIRE', key, 60000)
38 return {1, math.floor(tokens)}
39 else
40 redis.call('HMSET', key, 'tokens', tokens, 'lastRefill', now)
41 redis.call('PEXPIRE', key, 60000)
42 local waitTime = math.ceil((1 - tokens) / refillRate * 1000)
43 return {0, waitTime}
44 end
45 `;
46
47 const result = await redis.eval(lua, 1, bucketKey, maxTokens, refillRate, now) as number[];
48
49 if (result[0] === 1) {
50 return { allowed: true, remaining: result[1], retryAfter: null };
51 }
52 return { allowed: false, remaining: 0, retryAfter: result[1] };
53}
54
55// Middleware Express
56import { Request, Response, NextFunction } from "express";
57
58export function rateLimitMiddleware() {
59 return async (req: Request, res: Response, next: NextFunction) => {
60 const clientKey = req.ip || "unknown";
61 const result = await tokenBucket(clientKey);
62
63 res.setHeader("X-RateLimit-Limit", 100);
64 res.setHeader("X-RateLimit-Remaining", result.remaining);
65
66 if (!result.allowed) {
67 res.setHeader("Retry-After", Math.ceil((result.retryAfter || 1000) / 1000));
68 return res.status(429).json({ error: "Too Many Requests" });
69 }
70
71 next();
72 };
73}