Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict the user to make limited request per Second

Environment:
Java-EE based web application


Problem:
Need to restrict user to make more than 5(for example) request within same Second (BOTs mainly)


Solution :
As a basic design I am planning to have 2 synchronized Map in application scope

Map<String, Map<Long, Integer>>

String is for sessionId of request

Long is for current second representation

Integer is to hold request count


Process:

Step 0:

Configuring a Filter to intercept each request

Step 1:

determine the map I will see if current minute is odd then I will add data on mapOne and I will clear the mapTwo

Step 2:

process map

int requestNoForThisSecond = mapXX.get(request.getSession().getId()).get(currentSecondRepresantationInLong);
if(requestNoForThisSecond <= 5){
          requestNoForThisSecond++; 
          mapXX.get(request.getSession().getId()).put(currentSecondRepresantationInLong, requestNoForThisSecond);
}else{
         response.sendRedirect();// redirect to some captcha page
    } 

Step 4:

also remove the session entry if session expires / user logs out


This is very basic design for the problem

Any one of you have any better idea/suggestion ?

like image 897
jmj Avatar asked Jan 04 '12 12:01

jmj


People also ask

How to handle rate limiting?

A better way: randomization While the reset option is one way to deal with rate limiting, you may want more granular control over your rate limit handling. For example, you might have a specific retry timeframe that you want to follow and not wait for the minute window to pass for your entire rate limit to be reset.

How does rate limiter work?

How does rate limiting work? Rate limiting runs within an application, rather than running on the web server itself. Typically, rate limiting is based on tracking the IP addresses that requests are coming from, and tracking how much time elapses between each request.


1 Answers

First of all, I think you should forget the idea of the session id, and use IP addresses instead. You do not expect the bot to be sending you the necessary cookies so that you can keep track of its session, do you?

Secondly, I think that your approach is unnecessarily complicated. All you need is a map of IP-address to array-of-time[N] where N is a fixed number, the number of requests you are planning to allow per second. (I am assuming it will be relatively low.) So, every time you have a request from a given IP, you shift the contents of the array down by one, and you add the time of the new request to the end of the array. Then, you subtract the time at index 0 of your array from the time at the last index, and this gives you the amount of time it took that IP to send you N requests, which you can trivially convert to number of requests per second.

Also, you might find this discussion interesting: https://softwareengineering.stackexchange.com/questions/126700/development-of-a-bot-web-crawler-detection-system

like image 183
Mike Nakis Avatar answered Nov 03 '22 18:11

Mike Nakis