Flutter资源限制插件shelf_limiter的使用

发布于 1周前 作者 sinazl 来自 Flutter

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 文件中添加了 shelfshelf_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 包装起来,同时传入速率限制器和并发限制器。还提供了 onRateLimitedonConcurrencyLimited 回调来处理超出限制的情况,分别返回 429 Too Many Requests503 Service Unavailable 响应。
  5. 最后,创建并启动了一个 shelf 服务器,监听所有 IPv4 地址的8080端口。

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

回到顶部