Security
Rate limiter
Get started | Expo Starter
Enable rate limiter for REST API
To enhance the security of your API, consider implementing throttling with Vercel/KVM. This method helps safeguard against brute-force attacks by limiting the number of requests a user can make within a given time frame, effectively preventing malicious attempts to access your system.
import { kv } from "@vercel/kv";
const limit = 10;
const window_seconds = 60;
const rateLimit = t.middleware(async ({ ctx, next }) => {
const interval = Math.floor(Date.now() / 1000 / window_seconds);
const key = `rate-limit:${ctx.session?.id}:${interval}`;
const current = await kv.incr(key, { ex : window_seconds, nx: true});
if (current > limit) {
throw new TRPCError({
code: "TOO_MANY_REQUESTS",
message: "You are being rate limited.",
});
}
return next();
});
export const rateLimitedProcedure = t.procedure.use(rateLimit);
For Self-hosted, you can use Redis or Memcached to implement rate limiting.
pnpm install ioredis
Add REDIS_URL
to environment variable :
REDIS_URL=redis://default:password@localhost:6379
Edit the server.ts
file to implement rate limiting with Redis:
import Redis from 'ioredis';
import { TRPCError } from '@trpc/server';
const redis = new Redis(); // Connects to the default Redis server (localhost:6379)
const limit = 10;
const window_seconds = 60;
const rateLimit = t.middleware(async ({ ctx, next }) => {
const interval = Math.floor(Date.now() / 1000 / window_seconds);
const key = `rate-limit:${ctx.session?.id}:${interval}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, window_seconds); // Set expiration only if it's the first increment
}
if (current > limit) {
throw new TRPCError({
code: "TOO_MANY_REQUESTS",
message: "You are being rate limited.",
});
}
return next();
});