Luracast / Restler

Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and/or RESTful API
http://luracast.com/products/restler/
GNU Lesser General Public License v2.1
1.36k stars 315 forks source link

Implementing Rate Limiting in persistance layer #634

Closed roynasser closed 4 years ago

roynasser commented 4 years ago

Hi Everyone, Hi @Arul- . Hope everyone is safe in this strange time!!!

I'm implementing some rate limit using Restler's builtin functions and I have some doubts.

How "pluggable" is RateLimit.php meant to be? Are we meant to implement our own RateLimit, or extende the current one?

How do I select a different limit storage (we use APC for cache, but want to use shared Redis for limits) for example... Also, I'd like to implement 429 Logging throughout, is that possible? Finaly, how do I make RateLimiting use my APIKey as an ID/bucket for the limit? (Each APIKey has their usage quota)

thanks!!

Arul- commented 4 years ago

Let me answer one by one

Restler is using Defaults::$cacheClass which defaults to 'Luracast\\Restler\\HumanReadableCache'

You can override this by replacing your own cache class that implements iCache interface

Just create a cache class that stores in Redis for example

roynasser commented 4 years ago

Hi Arul, thanks for your response!

I started creating a "custom" RateLimit filter, changing things around a bit... Nonetheless, I already use the Default::cacheClass in order to cache routes in APC... I want to have different caches for RateLimit, Routes, etc...

Arul- commented 4 years ago

Understood

Arul- commented 4 years ago

how do I make RateLimiting use my APIKey as an ID/bucket for the limit? (Each APIKey has their usage quota)

Your Auth class should update Defaults::$userIdentifierClass; which defaults to Luracast\Restler\User class. you can also replace it with any class that implements iIdentifyUser interface.

Basically your Auth class calls User:: setUniqueIdentifier method and passes a unique identifier which can also be the api key!

roynasser commented 4 years ago

Can you clear for me if this is a good way of doing it?

I'm customizing RateLimit.php to override the $user::getUniqueIdentifier() with an ID coming from our authentication layer.

I'm going to send an event for 429 from RateLimit.php or use onComplete in my endpoint.php

roynasser commented 4 years ago

how do I make RateLimiting use my APIKey as an ID/bucket for the limit? (Each APIKey has their usage quota)

Your Auth class should update Defaults::$userIdentifierClass; which defaults to Luracast\Restler\User class. you can also replace it with any class that implements iIdentifyUser interface.

Basically your Auth class calls User:: setUniqueIdentifier method and passes a unique identifier which can also be the api key!

This sounds better than what I'm doing.... I'll investigate!!

Arul- commented 4 years ago

in your auth class do

<? //inside the authenticate method
$user = Defaults::$userIdentifierClass;
if (method_exists($user, 'setUniqueIdentifier')) {
    $user::setUniqueIdentifier($api_key);
}
Arul- commented 4 years ago

Extending the class and overriding the relevant methods is the only option for the following

Arul- commented 4 years ago

continue to ask questions here if needed