Rate Limit
Better Auth는 트래픽 관리와 악용 방지를 돕는 내장 rate limiter를 포함하고 있습니다. 기본적으로 프로덕션 모드에서 rate limiter는 다음과 같이 설정됩니다:
- Window: 60초
- Max Requests: 100개의 요청
auth.api를 사용하여 만든 서버 측 요청은 rate limiting의 영향을 받지 않습니다. Rate limit는 클라이언트가 시작한 요청에만 적용됩니다.
betterAuth 함수에 rateLimit 객체를 전달하여 이러한 설정을 쉽게 커스터마이징할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
rateLimit: {
window: 10, // 초 단위 시간 윈도우
max: 100, // 윈도우 내 최대 요청 수
},
})Rate limiting은 기본적으로 개발 모드에서 비활성화됩니다. 활성화하려면 enabled를 true로 설정하세요:
export const auth = betterAuth({
rateLimit: {
enabled: true,
//...기타 옵션
},
})기본 설정 외에도 Better Auth는 특정 경로에 대한 커스텀 규칙을 제공합니다. 예를 들어:
/sign-in/email: 10초 내에 3개의 요청으로 제한됩니다.
또한 플러그인도 특정 경로에 대한 커스텀 규칙을 정의합니다. 예를 들어 twoFactor 플러그인은 다음과 같은 커스텀 규칙을 가지고 있습니다:
/two-factor/verify: 10초 내에 3개의 요청으로 제한됩니다.
이러한 커스텀 규칙은 민감한 작업이 더 엄격한 제한으로 보호되도록 보장합니다.
Rate Limit 설정하기
연결 IP 주소
Rate limiting은 연결 IP 주소를 사용하여 사용자가 만든 요청 수를 추적합니다. 기본적으로 확인되는 헤더는 프로덕션 환경에서 일반적으로 사용되는 x-forwarded-for입니다. 사용자의 IP 주소를 추적하기 위해 다른 헤더를 사용하는 경우 이를 지정해야 합니다.
export const auth = betterAuth({
//...기타 옵션
advanced: {
ipAddress: {
ipAddressHeaders: ["cf-connecting-ip"], // Cloudflare 특정 헤더 예제
},
},
rateLimit: {
enabled: true,
window: 60, // 초 단위 시간 윈도우
max: 100, // 윈도우 내 최대 요청 수
},
})Rate Limit Window
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
window: 60, // 초 단위 시간 윈도우
max: 100, // 윈도우 내 최대 요청 수
},
})특정 경로에 대한 커스텀 규칙도 전달할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
window: 60, // 초 단위 시간 윈도우
max: 100, // 윈도우 내 최대 요청 수
customRules: {
"/sign-in/email": {
window: 10,
max: 3,
},
"/two-factor/*": async (request)=> {
// rate limit window와 max를 반환하는 커스텀 함수
return {
window: 10,
max: 3,
}
}
},
},
})특정 경로에 대해 rate limiting을 비활성화하려면 false로 설정하거나 커스텀 규칙 함수에서 false를 반환할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
customRules: {
"/get-session": false,
},
},
})스토리지
기본적으로 rate limit 데이터는 메모리에 저장되며, 이는 많은 사용 사례, 특히 서버리스 환경에는 적합하지 않을 수 있습니다. 이를 해결하기 위해 데이터베이스, 보조 스토리지 또는 커스텀 스토리지를 사용하여 rate limit 데이터를 저장할 수 있습니다.
데이터베이스 사용
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
storage: "database",
modelName: "rateLimit", //선택 사항, 기본적으로 "rateLimit"이 사용됩니다
},
})데이터베이스에 rate limit 테이블을 생성하려면 migrate를 실행하세요.
npx @better-auth/cli migrate보조 스토리지 사용
보조 스토리지가 설정되어 있다면 이를 사용하여 rate limit 데이터를 저장할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
storage: "secondary-storage"
},
})커스텀 스토리지
위의 솔루션 중 어느 것도 사용 사례에 맞지 않는 경우 customStorage를 구현할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...기타 옵션
rateLimit: {
customStorage: {
get: async (key) => {
// rate limit 데이터 가져오기
},
set: async (key, value) => {
// rate limit 데이터 설정
},
},
},
})Rate Limit 오류 처리하기
요청이 rate limit를 초과하면 Better Auth는 다음 헤더를 반환합니다:
X-Retry-After: 사용자가 다른 요청을 할 수 있을 때까지의 시간(초).
클라이언트 측에서 rate limit 오류를 처리하려면 전역적으로 또는 요청별로 관리할 수 있습니다. Better Auth 클라이언트는 Better Fetch를 감싸고 있으므로 rate limit 오류를 처리하기 위해 fetchOptions를 전달할 수 있습니다
전역 처리
import { createAuthClient } from "better-auth/client";
export const authClient = createAuthClient({
fetchOptions: {
onError: async (context) => {
const { response } = context;
if (response.status === 429) {
const retryAfter = response.headers.get("X-Retry-After");
console.log(`Rate limit 초과. ${retryAfter}초 후에 재시도하세요`);
}
},
}
})요청별 처리
import { authClient } from "./auth-client";
await authClient.signIn.email({
fetchOptions: {
onError: async (context) => {
const { response } = context;
if (response.status === 429) {
const retryAfter = response.headers.get("X-Retry-After");
console.log(`Rate limit 초과. ${retryAfter}초 후에 재시도하세요`);
}
},
}
})스키마
rate limit 데이터를 저장하기 위해 데이터베이스를 사용하는 경우 다음 스키마가 필요합니다:
테이블 이름: rateLimit
| Field Name | Type | Key | Description |
|---|---|---|---|
| id | string | 데이터베이스 ID | |
| key | string | - | 각 rate limit 키의 고유 식별자 |
| count | integer | - | 초 단위 시간 윈도우 |
| lastRequest | bigint | - | 윈도우 내 최대 요청 수 |