mirror of
https://github.com/directus/directus.git
synced 2026-01-28 23:27:59 -05:00
update env
This commit is contained in:
@@ -31,6 +31,8 @@ const defaults = {
|
||||
REDIS_PASSWORD: null,
|
||||
},
|
||||
rateLimits: {
|
||||
RATE_LIMIT_TYPE: 'redis',
|
||||
CACHE_TYPE: 'redis',
|
||||
CONSUMED_POINTS_LIMIT: 5,
|
||||
CONSUMED_RESET_DURATION: 1,
|
||||
EXEC_EVENLY: true,
|
||||
|
||||
64
api/src/middleware/cache.ts
Normal file
64
api/src/middleware/cache.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* RateLimiter using Redis
|
||||
* and rate-limiter-flexible
|
||||
* can extend with further options
|
||||
* in future
|
||||
*/
|
||||
import { RequestHandler } from 'express';
|
||||
import redis from 'redis';
|
||||
import { RateLimiterRedis } from 'rate-limiter-flexible';
|
||||
import { HitRateLimitException } from '../exceptions';
|
||||
import { RedisNotFoundException } from '../exceptions';
|
||||
import env from '../env';
|
||||
|
||||
const redisClient = redis.createClient({
|
||||
enable_offline_queue: false,
|
||||
host: env.REDIS_HOST,
|
||||
port: env.REDIS_PORT,
|
||||
password: env.REDIS_PASSWORD,
|
||||
});
|
||||
|
||||
const rateLimiter: RequestHandler = (req, res, next) => {
|
||||
try {
|
||||
// first need to check that redis is running!
|
||||
if (!redisClient) {
|
||||
throw new RedisNotFoundException('Redis client does not exist');
|
||||
}
|
||||
// options for the rate limiter are set below. Opts can be found
|
||||
// at https://github.com/animir/node-rate-limiter-flexible/wiki/Options
|
||||
const opts = {
|
||||
storeClient: redisClient,
|
||||
points: 5, // Number of points
|
||||
duration: 5, // Number of seconds before consumed points are reset.
|
||||
|
||||
// Custom
|
||||
execEvenly: true, // delay actions after first action - this may need adjusting (leaky bucket)
|
||||
blockDuration: 0, // Do not block if consumed more than points
|
||||
keyPrefix: 'rlflx', // must be unique for limiters with different purpose
|
||||
};
|
||||
|
||||
const rateLimiterRedis = new RateLimiterRedis(opts);
|
||||
|
||||
rateLimiterRedis
|
||||
.consume(req.ip)
|
||||
.then((rateLimiterRes) => {
|
||||
// everything is ok - can put addition logic in there later for users etc
|
||||
next();
|
||||
})
|
||||
.catch((rejRes) => {
|
||||
if (rejRes instanceof RedisNotFoundException) {
|
||||
throw new RedisNotFoundException('Redis insurance limiter not set up');
|
||||
} else {
|
||||
// If there is no error, rateLimiterRedis promise rejected with number of ms before next request allowed
|
||||
const secs = Math.round(rejRes.msBeforeNext / 1000) || 1;
|
||||
res.set('Retry-After', String(secs));
|
||||
res.status(429).send('Too Many Requests');
|
||||
throw new HitRateLimitException(`Too many requests, retry after ${secs}.`);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export default rateLimiter;
|
||||
Reference in New Issue
Block a user