https://supertokens.com/ logo
#support-questions
Title
# support-questions
d

DanielAtStruggly

01/20/2023, 8:11 AM
Hi SuperTokens team, I am using Supertokens with NestJs. All my APIs are rate limited via https://docs.nestjs.com/security/rate-limiting. Do you have any clue to let the SuperTokens middleware (for calls like e.g. /auth/signin) be aware of these rate-limiting settings?
r

rp

01/20/2023, 8:49 AM
hey @DanielAtStruggly
you essentially have to covert the rate limiting to a middleware and apply that middleware before the supertokens middleware runs
d

DanielAtStruggly

01/20/2023, 10:12 AM
Hey @rp, did you do that already or ideally have some sample code? It would be outstanding to inject the already available NestJS rate-limiting mechanism for that.
r

rp

01/20/2023, 10:28 AM
maybe @porcellus can help out here
p

porcellus

01/20/2023, 10:28 AM
hi
I'll check it out
d

DanielAtStruggly

01/20/2023, 10:30 AM
Thanks guys!
p

porcellus

01/20/2023, 10:49 AM
Sadly, I don't see any straightforward way to apply this to our middleware :/ One thing you could test is trying to apply this as globally as possible, by adding this provider to the module
Copy code
{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
(they write about this at the start of the guide you linked)
if that doesn't work, then it'd have to be a second middleware that is applied before our middleware
r

rp

01/20/2023, 10:53 AM
@porcellus can you show an example of how a new middleware can be created that does this please?
p

porcellus

01/20/2023, 10:54 AM
Sure, I'll get back with an example in 1-2h
d

DanielAtStruggly

01/20/2023, 11:29 AM
I already added the ThrottlerGuard globally via
provide: APP_GUARD
. Unfortunately, this doesn't help with the supertokens middleware 🙁 .
p

porcellus

01/20/2023, 1:12 PM
This is what I came up with:
Copy code
ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { middleware } from 'supertokens-node/framework/express';
import { RateLimiterMemory } from 'rate-limiter-flexible';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  supertokensMiddleware: any;
  rateLimiter: RateLimiterMemory;
  combinedMiddleware: any;

  constructor() {
    this.rateLimiter = new RateLimiterMemory({
      points: 2, // 2 requests
      duration: 60, // per 60 second by IP
    });
    this.supertokensMiddleware = middleware();

    this.combinedMiddleware = (req, res, next) => {
      this.rateLimiter
        .consume(req.ip)
        .then(() => {
          this.supertokensMiddleware(req, res, next);
        })
        .catch(() => {
          res.status(429).send('Too Many Requests');
        });
    };
  }

  use(req: Request, res: any, next: () => void) {
    return this.combinedMiddleware(req, res, next);
  }
}
There are a couple of ways around this, but this lib seems very flexible (it's in the name! 😄 ), popular and maintained.
One caveat: this will add rate-limiting to all your APIs, so you might want to limit where you are using the
AuthMiddleware
d

DanielAtStruggly

01/20/2023, 1:19 PM
Hey @porcellus this is super nice. Many thanks for the code excerpt! I'll give it a try! Have a lovely Friday + weekend. Thanks! 🎉
r

rp

01/20/2023, 1:19 PM
thanks @porcellus !
p

porcellus

01/20/2023, 1:42 PM
happy to help 🙂
d

DanielAtStruggly

01/21/2023, 2:05 PM
Hey @porcellus I tried your approach - it's working 😀 ! Thanks a lot. I avoid the caveat you mentioned by using a specific apiBasePath. So, the supertokens middleware is only called for this specific apiBasePath.
p

porcellus

01/21/2023, 2:22 PM
that's good to hear 🙂
also, that's a good solution the caveat. I mentioned it because in the guide the middleware is applied to "*" IIRC
7 Views