VuePressVuePress
首页
  • 基础
  • UI
  • JavaScript
  • CSS
  • postcss
  • Vue3
  • Vue的设计与实现
  • 前端常用插件
  • PHP
  • Laravel
  • Linux
  • 线性代数
Category
AI
jiyun
Timeline
首页
  • 基础
  • UI
  • JavaScript
  • CSS
  • postcss
  • Vue3
  • Vue的设计与实现
  • 前端常用插件
  • PHP
  • Laravel
  • Linux
  • 线性代数
Category
AI
jiyun
Timeline
  • 基础知识

    • 表单验证
    • 限流1
      • 代码解析
      • 作用
      • 注意事项
      • 如何使用
        • 1. 更新 AppServiceProvider 文件
        • 2. 使用限流逻辑
        • 总结
  • 请求

    • request
  • 认证

    • auth
  • 验证

    • fail
  • migrations

    • migration
  • eloquent

    • eloquent
    • updateOrCreate
  • seeder

    • seeder
    • seeder2
  • 套件

    • precognition
  • 进阶

    • Cache 缓存
  • 最佳实践

    • CRUD 最佳实践
    • 将用户定位到他的前缀域名
    • 服务类仓储类查询类
    • 接口和实现
    • laravel 中 trait 引导机制
    • 使用阿里云oss上传图片
  • plugins

    • IDE Helper Generator for Laravel
namespace App\Providers;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        RateLimiter::for('weather', function(Request $request) {
            return Limit::perMinute(5)
                ->by($request->user()?->id ?: $request->ip());
        });
    }
}

这段代码是一个 Laravel 项目中的服务提供者(ServiceProvider)代码,具体实现了一个限流(Rate Limiting)功能。下面是对这段代码的详细解释:

代码解析

  1. boot 方法
    boot 方法是服务提供者中的一个特殊方法,当所有服务提供者都注册之后,该方法会自动调用。 通常用来注册事件监听器,或者是其他框架初始化工作。
  2. 限流逻辑
    RateLimiter::for('weather', function(Request $request) {
    return Limit::perMinute(5)
    ->by($request->user()?->id ?: $request->ip());
    });
    
    • RateLimiter::for('weather'...:定义了一个名为 weather 的速率限制器。
    • return Limit::perMinute(5):设置这个操作每分钟只能执行 5 次。
    • ->by($request->user()?->id ?: $request->ip()):限流依据是用户 ID,如果用户未登录(即没有用户 ID),则使用用户的 IP 地址进行限流。

作用

这段代码的作用是防止用户频繁请求 weather 接口。每个用户每分钟最多只能请求 5 次这个接口。如果用户未登录,则基于 IP 地址进行限流。这种机制可以有效防止接口被滥用,保护服务器资源。

注意事项

  1. 如果需要对 weather 接口进行更细粒度的限流,可以调整 perMinute(5) 中的数值。
  2. 这段代码中的 $request->user()?->id 使用的是 PHP 8.0 引入的安全访问运算符(nullsafe operator),确保即使 $request->user() 返回 null,也不会引发错误。
  3. 确保 RateLimiter 和 Limit 已正确引入,通常情况下它们在 Illuminate\Support\Facades\RateLimiter 和 Illuminate\Cache\RateLimiting\Limit 中。

通过设置合适的限流规则,可以有效保护 API 免受滥用,同时也能保证合法用户的正常使用。

如何使用

要在 Laravel 应用中使用限流逻辑,可以按照以下步骤进行配置和使用。以下是详细的步骤说明:

1. 更新 AppServiceProvider 文件

首先,需要在 AppServiceProvider 中定义限流逻辑。确保你已经将限流逻辑添加到 boot 方法中,如之前提到的那。

2. 使用限流逻辑

接下来,你需要在路由或控制器中应用这个限流逻辑。假设你有一个天气接口,你可以在路由中使用中间件来应用限流。

2.1 在路由中应用限流

在 routes/web.php 或 routes/api.php 中,你可以使用 throttle 中间件来应用限流。

use Illuminate\Support\Facades\Route;

Route::middleware(['throttle:weather'])->group(function () {
    Route::get('/weather', 'WeatherController@getWeather');
});

2. 在控制器中应用限流

如果你想在控制器中直接应用限流,可以在控制器方法中使用 throttle 中间件:

namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;

class WeatherController extends BaseController
{
    public function __construct()
    {
        $this->middleware('throttle:weather');
    }

    public function getWeather(Request $request)
    {
        // 获取天气数据的逻辑
        return response()->json(['weather' => 'sunny']);
    }
}

3. 配置 throttle 中间件

在 app/Http/Kernel.php 文件中,确保 throttle 中间件已注册:

protected $routeMiddleware = [
    // 其他中间件
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

4. 测试限流逻辑

通过访问 /weather 接口进行测试,每分钟超过 5 次请求时,应该会返回 HTTP 429 错误(Too Many Requests)。

5. 自定义错误响应(可选)

你可以自定义限流超出后的错误响应。在 app/Exceptions/Handler.php 中重写 prepareResponse 方法:

protected function prepareResponse($request, Throwable $e)
{
    if ($e instanceof \Illuminate\Http\Exceptions\ThrottleRequestsException) {
        return response()->json(['error' => 'Too Many Requests'], 429);
    }

    return parent::prepareResponse($request, $e);
}

总结

通过上述步骤,你可以在 Laravel 应用中实现并使用限流逻辑,以防止用户过于频繁地访问某些接口。限流机制可以有效保护你的应用免受滥用,同时保证服务的稳定性和可用性。

Last Updated:
Contributors: BaronYan
Prev
表单验证