Skip to content

perseidesjs/medusa-plugin-rate-limit

Repository files navigation

Perseides logo

@perseidesjs/medusa-plugin-rate-limit

npm version Tests No dependencies GitHub license

A simple rate-limitting plugin for Medusa.

Purpose

This plugin was mainly built to protect your MedusaJS application from abuse. This plugin allows you to easily manage request limits without stepping outside the familiar Medusa environment.

Why Rate Limiting Matters

  1. Shield Against Attacks: Prevent Denial of Service (DoS) attempts by capping the number of requests from a single source.
  2. Boost Security: Thwart brute force attacks and other automated threats by controlling request frequency.
  3. Easy Setup: Seamlessly integrate rate limiting into your existing Medusa configuration files.

Installation

npm install @perseidesjs/medusa-plugin-rate-limit

Usage

This plugin uses the CacheModule available (InMemory, Redis, etc.) under the hood and exposes a simple middleware to limit the number of requests per IP address.

How to use

If you want to start restricting certain routes, you can import the defaultRateLimit middleware from the plugin and then use it as follows:

// src/api/middlewares.ts
import { defineMiddlewares } from "@medusajs/medusa"
import { defaultRateLimit } from '@perseidesjs/medusa-plugin-rate-limit'

export default defineMiddlewares({
  routes: [
    {
      matcher: "/store/custom*",
      middlewares: [defaultRateLimit()],
    },
  ],
})

You can also pass some custom options to have a complete control over the rate limiting mechanism as follows:

// src/api/middlewares.ts
import { defineMiddlewares } from "@medusajs/medusa"
import { defaultRateLimit } from '@perseidesjs/medusa-plugin-rate-limit'

export default defineMiddlewares({
  routes: [
    {
      matcher: "/store/custom*",
      middlewares: [defaultRateLimit({
				limit: 10,
				window: 60,
			})],
    },
  ],
})
In this example, the rate limiting mechanism will allow 10 requests per minute per IP address.

Granular control over rate limiting

The choice of having options directly inside the middleware instead of globally inside the plugin options was made to provide greater flexibility. This approach allows users to be more or less restrictive on certain specific routes. By specifying options directly within the middleware, you can tailor the rate limiting mechanism to suit the needs of individual routes, rather than applying a one-size-fits-all configuration globally. This ensures that you can have fine-grained control over the rate limiting behavior, making it possible to adjust the limits based on the specific requirements of each route.

Additionally, you can still use the plugin options to update the default global values, such as the limit and window. This allows you to set your own default values that will be applied across many routes, while still having the flexibility to specify more granular settings for specific routes. By configuring the plugin options, you can establish a baseline rate limiting policy that suits the majority of your application, and then override these defaults as needed for particular routes.

Default configuration

Option Type Default Description
limit Number 5 The number of requests allowed in the given time window
window Number 60 The time window in seconds

Plugin options

// medusa-config.js
const { loadEnv, defineConfig } = require('@medusajs/framework/utils')

loadEnv(process.env.NODE_ENV, process.cwd())

module.exports = defineConfig({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    http: {
      storeCors: process.env.STORE_CORS,
      adminCors: process.env.ADMIN_CORS,
      authCors: process.env.AUTH_CORS,
      jwtSecret: process.env.JWT_SECRET || "supersecret",
      cookieSecret: process.env.COOKIE_SECRET || "supersecret",
    },
  },
  plugins: [
    {
      resolve: "@perseidesjs/medusa-plugin-rate-limit",
      options: {
        limit: 50,
        window: 60,
      },
    },
  ],
})

License

This project is licensed under the MIT License - see the LICENSE file for details