본문으로 건너뛰기
버전: master

Rate Limiting

Introduction​

Laravel은 애플리케이션의 cache와 함께 사용할 수 있는 간단한 요청 제한 추상화 기능을 제공합니다. 이를 통해 지정된 시간 동안 특정 동작을 손쉽게 제한할 수 있습니다.

들어오는 HTTP 요청의 요청 제한(rate limiting)에 관심이 있으시다면, rate limiter middleware documentation를 참고하시기 바랍니다.

Cache Configuration​

일반적으로 요청 제한기는 애플리케이션 cache 설정 파일 내의 default 키에 정의된 기본 애플리케이션 캐시를 사용합니다. 그러나 요청 제한기에서 사용할 캐시 드라이버를 지정하려면, 애플리케이션의 cache 설정 파일에 limiter 키를 추가하여 지정할 수 있습니다:

'default' => env('CACHE_STORE', 'database'),

'limiter' => 'redis', // [tl! add]

Basic Usage​

요청 제한기는 Illuminate\Support\Facades\RateLimiter 파사드를 사용하여 조작할 수 있습니다. 가장 간편하게 사용할 수 있는 메서드는 attempt 메서드로, 지정된 초(sec) 동안 주어진 콜백을 요청 제한합니다.

attempt 메서드는 더 이상 남은 시도 가능 횟수가 없으면 false를 반환하며, 그렇지 않으면 attempt 메서드는 콜백의 실행 결과나 true를 반환합니다. attempt 메서드의 첫 번째 인수는 요청 제한에 사용할 "키(key)"로, 제한을 적용할 특정 동작을 대표하는 임의의 문자열을 사용할 수 있습니다:

use Illuminate\Support\Facades\RateLimiter;

$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Send message...
}
);

if (! $executed) {
return 'Too many messages sent!';
}

필요하다면, attempt 메서드의 네 번째 인수로 "갱신 주기(decay rate)"를 지정할 수 있습니다. 이는 제한 횟수가 초기화되기까지 남은 초(sec)를 의미합니다. 예를 들어, 위 예제에서 2분(120초) 동안 총 5회 시도할 수 있도록 수정할 수 있습니다:

$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// Send message...
},
$decayRate = 120,
);

Manually Incrementing Attempts​

요청 제한기를 좀 더 세밀하게 수동으로 다루고 싶다면, 다양한 메서드를 사용할 수 있습니다. 예를 들어, tooManyAttempts 메서드를 사용하면 특정 요청 제한 키가 1분 내 최대 허용 횟수를 초과하였는지 확인할 수 있습니다:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
return 'Too many attempts!';
}

RateLimiter::increment('send-message:'.$user->id);

// Send message...

또는, remaining 메서드를 사용하여 특정 키의 남은 시도 가능 횟수를 조회할 수 있습니다. 남은 재시도 가능 횟수가 있다면, increment 메서드를 호출하여 시도 횟수를 1 증가시킬 수 있습니다:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::increment('send-message:'.$user->id);

// Send message...
}

특정 요청 제한 키의 값을 한 번에 1보다 큰 값만큼 증가시키고 싶다면, increment 메서드에 원하는 증가 값을 전달하면 됩니다:

RateLimiter::increment('send-message:'.$user->id, amount: 5);

Determining Limiter Availability​

키에 더 이상 남은 시도 횟수가 없을 때, availableIn 메서드는 시도 가능 횟수가 다시 초기화(재시작)되기까지 남은 초를 반환합니다:

use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
$seconds = RateLimiter::availableIn('send-message:'.$user->id);

return 'You may try again in '.$seconds.' seconds.';
}

RateLimiter::increment('send-message:'.$user->id);

// Send message...

Clearing Attempts​

특정 요청 제한 키에 대한 시도 횟수를 clear 메서드를 사용하여 초기화할 수 있습니다. 예를 들어, 특정 메시지를 수신자가 읽었을 때 시도 횟수를 초기화할 수도 있습니다:

use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;

/**
* Mark the message as read.
*/
public function read(Message $message): Message
{
$message->markAsRead();

RateLimiter::clear('send-message:'.$message->user_id);

return $message;
}