Rate limit doesn't work at all in SvelteKit #986

Closed
opened 2026-03-13 08:15:44 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @elansx on GitHub (Apr 6, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create empty sveltekit project
  2. Set up better-auth
  3. Try to hit rate limit - nothing happens

Current vs. Expected behavior

I have tried all kinds of ways to get "hit" rate limit, but it doesn't. I can hit any endpoint unlimited times.

What version of Better Auth are you using?

1.2.5

Provide environment information

- Windows 10
- SvelteKit - 2.16.0
- Development environment

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

export const auth = betterAuth({
    database: mongodbAdapter(await getNativeClient()),
    emailAndPassword: {
        enabled: true,
        requireEmailVerification: true,
    },
    rateLimit: {
        enabled: true, 
        window: 10,
        max: 10,
        customRules: {
            "/email-otp/send-verification-otp": {
                    window: 10,
                    max: 2,
            },
        }
    },
    plugins: [
        emailOTP({ 
            async sendVerificationOTP({ email, otp }) { 
                console.log(email, otp)
            }
        })
    ]
});

Additional context

I have tried all possible configuration options and nothing seems to work.
Storage: memory/database, enabled: true/false, window: 1 - 100, max: 1 - 100 etc.

Do I miss something here?

Originally created by @elansx on GitHub (Apr 6, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create empty sveltekit project 2. Set up better-auth 3. Try to hit rate limit - nothing happens ### Current vs. Expected behavior I have tried all kinds of ways to get "hit" rate limit, but it doesn't. I can hit any endpoint unlimited times. ### What version of Better Auth are you using? 1.2.5 ### Provide environment information ```bash - Windows 10 - SvelteKit - 2.16.0 - Development environment ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript export const auth = betterAuth({ database: mongodbAdapter(await getNativeClient()), emailAndPassword: { enabled: true, requireEmailVerification: true, }, rateLimit: { enabled: true, window: 10, max: 10, customRules: { "/email-otp/send-verification-otp": { window: 10, max: 2, }, } }, plugins: [ emailOTP({ async sendVerificationOTP({ email, otp }) { console.log(email, otp) } }) ] }); ``` ### Additional context I have tried all possible configuration options and nothing seems to work. Storage: memory/database, enabled: true/false, window: 1 - 100, max: 1 - 100 etc. Do I miss something here?
Author
Owner

@elansx commented on GitHub (Apr 6, 2025):

Okay, it seems that SvelteKit doesn't provide client IP address in their headers (at least not with adapter-node).

So I have fix proposal for this in svelteHandler:

const svelteKitHandler = async ({
  auth,
  event,
  resolve
}) => {
  const { building } = await import('$app/environment').catch((e) => {
  }).then((m) => m || {});
  if (building) {
    return resolve(event);
  }
  const { request, url } = event;

 // Here we set client-ip header manually from event.getClientAddress() function
  if (event.getClientAddress && typeof event.getClientAddress === 'function') {
    request.headers.set('x-client-ip', event.getClientAddress());
  }

  if (isAuthPath(url.toString(), auth.options)) {
    return auth.handler(request);
  }
  return resolve(event);
};

Could this be solution?

For now I will use work around the set this header before svelteHandler in hooks, like this:

export const handle = async ({ event, resolve }) => {

        event.request.headers.set('x-client-ip', event.getClientAddress());
       
	return svelteKitHandler({ event, resolve, auth });
}

It's not like there is much of a difference, but should be mentioned at least somewhere in docs, but I think first variant is more preferable with this solution built-in directly into handler.

@elansx commented on GitHub (Apr 6, 2025): Okay, it seems that SvelteKit doesn't provide client IP address in their headers (at least not with adapter-node). So I have fix proposal for this in svelteHandler: ``` const svelteKitHandler = async ({ auth, event, resolve }) => { const { building } = await import('$app/environment').catch((e) => { }).then((m) => m || {}); if (building) { return resolve(event); } const { request, url } = event; // Here we set client-ip header manually from event.getClientAddress() function if (event.getClientAddress && typeof event.getClientAddress === 'function') { request.headers.set('x-client-ip', event.getClientAddress()); } if (isAuthPath(url.toString(), auth.options)) { return auth.handler(request); } return resolve(event); }; ``` Could this be solution? For now I will use work around the set this header before svelteHandler in hooks, like this: ``` export const handle = async ({ event, resolve }) => { event.request.headers.set('x-client-ip', event.getClientAddress()); return svelteKitHandler({ event, resolve, auth }); } ``` It's not like there is much of a difference, but should be mentioned at least somewhere in docs, but I think first variant is more preferable with this solution built-in directly into handler.
Author
Owner

@Kinfe123 commented on GitHub (Apr 7, 2025):

feel free to optimize the docs if you want.

@Kinfe123 commented on GitHub (Apr 7, 2025): feel free to optimize the docs if you want.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#986