Search code examples
phplaravelapibackendlumen

How to prevent automated requests to my Laravel/Lumen api?


So, I intend to completely separate my back-end from my front-end. I am learning about Laravel/Lumen API and I intend to return my database data in JSON format to be used by my front-end developers.

I have read several similar threads on Stack Overflow and watched some YouTube videos. Most of them suggested that I should generate a token for "authorized" users. However, the problem is that my project does not have a login system. All of my users are guest users. So, I can't first authorize a person and then generate a token for them.

From what I have understood (which could be flawed), Laravel API follows a RESTful system. So, it is stateless and I can't use CSRF token to check if a request comes from a submitted form and it is not automated. So, what other options do I have?

The reason that I want to separate automated requests from requests coming from forms is that sometimes I have to do heavy processing on some requests and I don't want an automated script to send mass requests and causes a DOS attack.

Any help is appreciated.


Solution

  • Rate limiting can help prevent automated scripts. Laravel has this implemented by default via the Throttle middleware. Default throttle is 60:1, throttle:60,1, translating to throttle if 60 attempts are registered within 1 minute.

    This middleware is applied to all routes, however, you can override this for individual routes and define custom values for number of attempts and time. Following example adapted from documentation configures the route to throttle if there's 30 attempts within 1 minute:

    Route::middleware('auth:api', 'throttle:30,1')->group(function () {
        Route::get('/user', function () {
            //
        });
    });
    

    There are other configuration options, please do refer to the documentation for more information on that.

    https://laravel.com/docs/7.x/routing#rate-limiting

    How does Laravel check that a guest user has sent too many requests?

    In very basic terms, Laravel keeps track of hits on a particular endpoint/domain by a particular IP in the application cache. The request domain and the IP are used as the cache key. Every time an endpoint is hit, no of attempts, stored in the cache, is incremented. If the no of attempts reaches the maximum number of allowed attempts within the time window specified in the throttle config applied on the route, that IP will be locked out for a while.

    Attempts are automatically cleared if there's no new hit in the time window.