instasent/ratelimit-bundle

此包提供了基于速率限制限制对操作调用功能

安装: 513

依赖者: 0

建议者: 0

安全: 0

星级: 1

观察者: 4

分支: 0

开放问题: 1

类型:symfony-bundle

v0.1.0 2016-08-01 12:37 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:31:13 UTC


README

Build Status Code Coverage Scrutinizer Code Quality

Latest Stable Version Total Downloads Latest Unstable Version License

此包提供了启用@RateLimit注解的功能,允许您限制对操作连接的数量。这在API中非常有用。

默认情况下,此包已准备与FOSOAuthServerBundle协同工作。它包含一个监听器,该监听器将OAuth令牌添加到缓存键。但是,您可以创建自己的密钥生成器,以便根据请求进行自定义速率限制。请参见下面的创建自定义密钥生成器

此包部分灵感来源于Ruud Kamphuis的GitHub gists:https://gist.github.com/ruudk/3350405

功能

  • 通过注解简单使用
  • 按控制器、操作甚至按HTTP方法自定义速率
  • 多个存储后端:Redis、Memcached和Doctrine缓存

安装

安装只需几个简单的步骤

步骤 1: 将包添加到composer.json

如果您还不熟悉Composer,请参阅https://getcomposer.org.cn。在composer.json中添加InstasentRateLimitBundle

{
    "require": {
        "Instasent/ratelimit-bundle": "1.x"
    }
}

现在通过运行以下命令让Composer下载此包

php composer.phar update Instasent/ratelimit-bundle

步骤 2: 启用包

在内核中启用此包

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Instasent\RateLimitBundle\InstasentRateLimitBundle(),
    );
}

步骤 3: 安装存储引擎

Redis

如果您想使用Redis作为存储引擎,则需要安装SncRedisBundle

Memcache

如果您想使用Memcache,则需要安装LswMemcacheBundle

Doctrine缓存

如果您想使用Doctrine缓存作为存储引擎,则需要安装DoctrineCacheBundle

有关详细信息,请参阅它们的文档。您可以使用storage_engine配置参数更改存储引擎。请参阅配置参考

配置

仅在生产环境中启用包

如果您只想在生产环境中启用此包(这样您就可以在没有担心限制的情况下测试开发环境),您可以使用enabled配置设置来完全启用/禁用包。默认情况下已启用

# config_dev.yml
instasent_rate_limit:
    enabled: false

配置参考

这是默认包配置

instasent_rate_limit:
    enabled:              true

    # The storage engine where all the rates will be stored
    storage_engine:       ~ # One of "redis"; "memcache"; "doctrine"

    # The redis client to use for the redis storage engine
    redis_client:         default_client

    # The memcache client to use for the memcache storage engine
    memcache_client:      default

    # The Doctrine Cache provider to use for the doctrine storage engine
    doctrine_provider:    null # Example: my_apc_cache

    # The HTTP status code to return when a client hits the rate limit
    rate_response_code:   429

    # Optional exception class that will be returned when a client hits the rate limit
    rate_response_exception:  null

    # The HTTP message to return when a client hits the rate limit
    rate_response_message:  'You exceeded the rate limit'

    # Should the ratelimit headers be automatically added to the response?
    display_headers:      true

    # What are the different header names to add
    headers:
        limit:                X-RateLimit-Limit
        remaining:            X-RateLimit-Remaining
        reset:                X-RateLimit-Reset

    # Rate limits for paths
    path_limits:
        path:                 ~ # Required
        methods:

            # Default:
            - *
        limit:                ~ # Required
        period:               ~ # Required

用法

简单的速率限制

要启用速率限制,您只需将注解添加到指定操作的文档块中

<?php

use Instasent\RateLimitBundle\Annotation\RateLimit;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Route(...)
 *
 * @RateLimit(limit=1000, period=3600)
 */
public function someApiAction()
{
}

按方法限制

还可以对特定的HTTP方法进行速率限制。这可以是字符串或方法数组的。如果没有指定方法参数,则所有未定义的其他方法都将受到限制。这允许在需要时添加默认速率限制。

<?php

use Instasent\RateLimitBundle\Annotation\RateLimit;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Route(...)
 *
 * @RateLimit(methods={"PUT", "POST"}, limit=1000, period=3600)
 * @RateLimit(methods={"GET"}, limit=1000, period=3600)
 * @RateLimit(limit=5000, period=3600)
 */
public function someApiAction()
{
}

按控制器限制

还可以将速率限制添加到控制器类中,而不是单个操作。这将作为所有操作(除了实际定义了自定义速率限制的操作)的默认速率限制。

<?php

use Instasent\RateLimitBundle\Annotation\RateLimit;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Ratelimit(methods={"POST"}, limit=100, period=10); // 100 POST requests per 10 seconds
 */
class DefaultController extends Controller
{
    /**
     * @ratelimit(method="POST", limit=200, period=10); // 200 POST requests to indexAction allowed.
     */
    public function indexAction()
    {
    }
}

创建自定义密钥生成器

如果您需要创建自定义密钥生成器,则需要注册一个监听器来监听ratelimit.generate.key事件

services:
    mybundle.listener.rate_limit_generate_key:
        class: MyBundle\Listener\RateLimitGenerateKeyListener
        tags:
            - { name: kernel.event_listener, event: 'ratelimit.generate.key', method: 'onGenerateKey' }
<?php

namespace MyBundle\Listener;

use Instasent\RateLimitBundle\Events\GenerateKeyEvent;

class RateLimitGenerateKeyListener
{
    public function onGenerateKey(GenerateKeyEvent $event)
    {
        $key = $this->generateKey();

        $event->addToKey($key);
        // $event->setKey($key); // to overwrite key completely
    }
}

请确保根据您控制器中的速率限制生成密钥。

设置自定义周期或限制

如果您需要根据存储在数据库中的客户端设置创建自定义周期/限制,则需要注册一个监听器来监听ratelimit.pre.create事件

services:
    mybundle.listener.rate_limit_pre_create:
        class: MyBundle\Listener\RateLimitFromDatabaseListener
        tags:
            - { name: kernel.event_listener, event: 'ratelimit.pre.create', method: 'findUserLimit' }
<?php

namespace MyBundle\Listener;

use Instasent\RateLimitBundle\Events\RateLimit;

class RateLimitFromDatabaseListener
{
    public function findUserLimit(RateLimit $event)
    {

        //TODO search value in database
        $event->setLimit($value);
    }
}

设置您自己的限制值

抛出异常

当达到速率限制时,而不是返回一个Response对象,也可以抛出异常。这允许您轻松地在另一个层面上处理速率限制,例如通过捕获kernel.exception事件。

运行测试

如果您想运行测试,请使用

./vendor/bin/phpunit ./Tests