Flutter资源限制插件shelf_limiter的使用

Flutter资源限制插件shelf_limiter的使用

shelf_limiter 是一个用于 Dart 中 Shelf 库的强大且高度可定制的中间件包,能够实现高效的速率限制。通过简单的设置保护你的 API 免受滥用并确保公平使用。

🌟 特性

特性 描述
🔧 可定制的速率限制 轻松设置最大请求数和时间窗口以满足您的需求。定义全局限制或特定端点的不同限制,控制客户端访问 API 的频率。
📜 自定义头部 在响应中添加和管理自定义头部,增强控制和透明度。
🚀 自定义响应 寻求更多控制?你做到了!当 API 限制被超出时,可以自定义并发送自己的响应。
🔗 简单集成 可无缝集成到现有的 Shelf 流水线中,只需少量设置即可快速应用速率限制。
🌐 端点特定限制 为不同的端点设置不同的速率限制。使用通配符模式(例如 /api/v1/*)对多个路由应用速率限制,允许您对高流量路由施加更严格的限制,同时对不太关键的部分提供更多的宽容度。

安装

在 pubspec.yaml 文件中添加 shelf_limiter:

dependencies:
  shelf_limiter: <latest>

然后运行:

dart pub get

或者简单地运行:

dart pub add shelf_limiter

使用

🔧 基本用法

快速有效地在 Shelf 应用程序中实现速率限制。以下是使用 shelfLimiter 中间件的基本示例:

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_limiter/shelf_limiter.dart';

void main() async {
  final limiter = shelfLimiter(
    RateLimiterOptions(
      maxRequests: 5,
      windowSize: const Duration(minutes: 1),
    ),
  );

  final handler =
      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);

  var server = await io.serve(handler, 'localhost', 8080);
  print('Server listening on port ${server.port}');
}

Response _echoRequest(Request request) => Response.ok('Request received');

在这个示例中,任何客户端每分钟最多只能发出 5 次请求。如果客户端超过此限制,他们将收到 429 Too Many Requests 响应。

🛠️ 增强 API 的自定义头部

使用自定义头部增强响应:

import 'dart:convert';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_limiter/shelf_limiter.dart';

void main() async {
  final options = RateLimiterOptions(
    headers: {
      'X-Custom-Header': 'Rate limited',
    },
  );

  final limiter = shelfLimiter(
    RateLimiterOptions(
      maxRequests: 5,
      windowSize: const Duration(minutes: 1),
      headers: options.headers,
    ),
  );

  final handler =
      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);

  var server = await io.serve(handler, 'localhost', 8080);
  print('Server listening on port ${server.port}');
}

Response _echoRequest(Request request) => Response.ok('Request received');

💡 自定义速率限制超限响应

当速率限制被超出时,提供有意义的反馈:

import 'dart:convert';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_limiter/shelf_limiter.dart';

void main() async {
  final options = RateLimiterOptions(
    headers: {
      'X-Custom-Header': 'Rate limited',
    },
    onRateLimitExceeded: (request) async {
      return Response(
        429,
        body: jsonEncode({
          'status': false,
          'message': "Uh, hm! Wait a minute, that's a lot of requests.",
        }),
        headers: {
          'Content-Type': 'application/json',
        },
      );
    },
  );

  final limiter = shelfLimiter(
    RateLimiterOptions(
      maxRequests: 5,
      windowSize: const Duration(minutes: 1),
      headers: options.headers,
      onRateLimitExceeded: options.onRateLimitExceeded,
    ),
  );

  final handler =
      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);

  var server = await io.serve(handler, 'localhost', 8080);
  print('Server listening on port ${server.port}');
}

Response _echoRequest(Request request) => Response.ok('Request received');

📌 高级用法与端点特定限制

当您希望微调速率限制策略并避免一刀切的方法时,shelfLimiterByEndpoint 是您最好的朋友。这个中间件允许您为不同的端点设置独特的速率限制,使您能够根据每个路由的需求量身定制限制。

示例 - 不同路由的自定义限制

以下是如何使用 shelfLimiterByEndpoint 使您的 API 如同一台运转良好的机器:

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_limiter/shelf_limiter.dart';

void main() async {
  final limiter = shelfLimiterByEndpoint(
    endpointLimits: {
      '/auth': RateLimiterOptions(
        maxRequests: 5,
        windowSize: const Duration(minutes: 1),
      ),
      '/data': RateLimiterOptions(
        maxRequests: 20,
        windowSize: const Duration(minutes: 1),
      ),
      '/api/v1/*': RateLimiterOptions( // Wildcard path matching
        maxRequests: 15,
        windowSize: const Duration(minutes: 2),
      ),
    },
    defaultOptions: RateLimiterOptions(
      maxRequests: 100,
      windowSize: const Duration(minutes: 1),
    ),
  );

  final handler =
      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);

  var server = await io.serve(handler, 'localhost', 8080);
  print('Server listening on port ${server.port}');
}

Response _echoRequest(Request request) => Response.ok('Request received');

更多关于Flutter资源限制插件shelf_limiter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter资源限制插件shelf_limiter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,shelf_limiter 是一个用于 Flutter 后端服务(通常与 Dart 的 shelf 服务器框架一起使用)的资源限制插件。它允许你限制并发请求的数量、请求速率等,以保护你的服务器免受资源耗尽攻击。以下是一个使用 shelf_limiter 的代码示例,展示了如何限制并发连接数和请求速率。

首先,确保你在 pubspec.yaml 文件中添加了 shelf 和 shelf_limiter 依赖:

dependencies:
  shelf: ^1.2.0
  shelf_limiter: ^2.0.0

然后,运行 flutter pub get 来获取这些依赖。

接下来,编写一个使用 shelf_limiter 的 Dart 服务器示例:

import 'dart:async';
import 'dart:io';

import 'package:shelf/shelf.dart';
import 'package:shelf_limiter/shelf_limiter.dart';

void main() async {
  // 创建一个基本的 shelf 处理器
  final handler = (Request request) async {
    return Response.ok('Hello, world!');
  };

  // 配置并发限制(例如,最多允许5个并发请求)
  final concurrencyLimiter = RateLimiter.window(
    duration: Duration(seconds: 1), // 时间窗口
    maxRequests: 5,                 // 最大请求数
  );

  // 配置速率限制(例如,每分钟最多允许30个请求)
  final rateLimiter = RateLimiter.perMinute(30);

  // 使用 shelf_limiter 包装处理器
  final limitedHandler = createLimiterMiddleware(
    handler: handler,
    rateLimiter: rateLimiter,
    concurrencyLimiter: concurrencyLimiter,
    onRateLimited: (Request request) {
      return Response.tooManyRequests('Too many requests, please try again later.');
    },
    onConcurrencyLimited: (Request request) {
      return Response.serviceUnavailable('Service is temporarily unavailable.');
    },
  );

  // 创建 shelf 服务器并运行
  final server = await shelf.serve(limitedHandler, InternetAddress.ANY_IP_V4, 8080);

  print('Serving at http://${server.address.host}:${server.port}');
}

在这个示例中:

  1. 我们首先创建了一个基本的 shelf 处理器 handler,它简单地对每个请求返回 “Hello, world!”。
  2. 使用 RateLimiter.window 创建了一个并发限制器,允许在1秒的时间窗口内最多有5个并发请求。
  3. 使用 RateLimiter.perMinute 创建了一个速率限制器,允许每分钟最多30个请求。
  4. 使用 createLimiterMiddleware 函数将处理器 handler 包装起来,同时传入速率限制器和并发限制器。还提供了 onRateLimited 和 onConcurrencyLimited 回调来处理超出限制的情况,分别返回 429 Too Many Requests 和 503 Service Unavailable 响应。
  5. 最后,创建并启动了一个 shelf 服务器,监听所有 IPv4 地址的8080端口。

这样,你的服务器现在就能够根据配置的速率和并发限制来处理请求了。如果请求超出限制,服务器会返回相应的错误响应。

回到顶部