防止滥用 API 服务使用

preventing abuse of API service usage

我计划在我的下一个 Web 项目中使用 Laravel,用于 backend。使用 Laravel 的 built-in 功能,我将构建一个 API 服务。所以我现在主要关心的是这种服务的安全性。 Laravel 的 API 节流中间件似乎是一个易于使用的解决方案,但它并不完全具备我需要的灵活性。或者至少我不知道它是否可以处理我的情况。

这是我的问题。希望有人能回答。

  1. 是否可以根据用户是否登录应用不同的节流逻辑? (执行 2-3 次节流检查)或者在同一请求中进行多次不同的节流检查。

  2. 有关调用 API 的 IP 的历史记录保存在哪里?是 HTTP headers 还是某种 cache/memcached/redis?

  3. 如果我想禁止某个 IP,然后检查它是否被禁止 - 是否有关于如何存储此类信息的好教程?如何将其与节流结合起来?模式示例或任何东西?一个建议会很好 :)

这是我最终要实现的逻辑的一个简单示例:

规则:

if IP throttling is enabled 
    then I don't want to check whether user is logged in or not

if (user is unauthorized) {
    throttle by IP.
    Throttle after 10 attempts within 1 minute

    if (number of times throttled within last 5 minutes = 0) {
        Retry-After: 1 minute
    }
    else if (number of times throttled within last 10 minutes > 1) {
        Retry-After: 10 minutes
    }
    else if (number of times throttled within last 30 minutes > 3) {
        Retry-After: 3 hours
    }
    else if (number of times throttled within last 8 hours minutes > 6) {
        ban IP for 1 week!!!
    }
}
else (user is authorised) {
    if (has permission: get_invoices) {
        throttle by JWT token.
        Throttle after 100 attempts within 1 minute

        if (number of times throttled within last 5 minutes = 0) {
            Retry-After: 5 minutes
        }
        else if (number of times throttled within last 30 minutes > 1) {
            ban user!!!
        }
    }
    else (user is logged in but doesn't have necessary permission
    {
        throttle by JWT token.

        Throttle after 50 attempts within 1 minute

        // apply logic different from user who has permission
    }

}

路线 N.r。 2, 3, 4 这可能是一个不同的逻辑。

所以我不能像这个例子中那样只使用一个中间件,因为它基于单个参数(IP、WTD、域或其他)并且不包含任何禁止逻辑

Route::group(['prefix' => 'api', 'middleware' => 'throttle:2,5'], function () {
    Route::get('invoice/{id}', function () {
        return $some invoice;
    });
});

我想收到一些关于此事的反馈。我正计划走向全球 :)

以下是我对您问题的回复:

  1. 是否可以根据用户是否登录应用不同的节流逻辑? (执行 2-3 次节流检查)或在同一请求中进行多次不同的节流检查。

    是的,你可以custom middleware and then call the throttle middleware from your custom middleware根据你想要的逻辑

  2. 有关调用 API 的 IP 的历史记录保存在哪里?它是 HTTP headers 还是某种 cache/memcached/redis?

    Laravel 不会开箱即用地记录 IP 地址。同样,您可以制作自定义中间件来执行此操作。要获取 IP 地址,您可以使用 $request->ip()

  3. 如果我想禁止某个 IP,然后检查它是否被禁止 - 是否有关于如何存储此类信息的好教程?如何将其与节流结合起来?模式示例或任何东西?一个建议会很好 :)

    是的,您可以将此逻辑构建到您为第二季度编写的自定义中间件中。要 store/retrieve 禁止的 IP 地址,您可以使用缓存或数据库。要 "integrate" 进行节流,您可以只使用两个中间件

我为您提供了一些非常简单的答案:)

自定义节流逻辑

Laravel 已经为您提供了特定的 class (App/Providers/RouteServiceProvider),您可以在其中根据需要指定自定义节流逻辑。下面是官方文档提供的例子:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
 
/**
 * Configure the rate limiters for the application.
 *
 * @return void
 */
protected function configureRateLimiting()
{
    RateLimiter::for('global', function (Request $request) {
        return Limit::perMinute(1000);
    });
}

有关更多信息,请查看文档:Defining Rate Limiters

IP 历史记录

documentation 没有显示与此相关的任何内容,我建议您在用户模型中包含列 ip 并在登录或注册后存储他们当前的 ip。但是如果你引用它以便将它添加到你的速率限制逻辑中,你可以包括(到 Limit class)方法 ->by($request->user()?->id ?: $request->ip()); 这是默认的方法API 节流。

通过 IP 禁止用户

我建议你使用 cybercog laravel-ban 制作的软件包,其中包括检查用户是否被禁止、通过特定电子邮件、ip 等禁止的方法。我一直在一些应用程序中使用它我制作,它真的很酷,易于安装和使用。