Skip to content

DDPRateLimiter

自定义方法和订阅的速率限制,以避免应用中的 WebSocket 消息负载过高。

¥Customize rate limiting for methods and subscriptions to avoid a high load of WebSocket messages in your app.

Galaxy(Meteor 托管)提供额外的应用保护,阅读更多 并使用我们的 30 天免费试用 尝试它。

¥Galaxy (Meteor hosting) offers additional App Protection, read more and try it with our free 30-day trial.

默认情况下,DDPRateLimiter 配置为单个规则。此规则将登录尝试、新用户创建和密码重置限制为每个连接每 10 秒 5 次尝试。可以通过调用 Accounts.removeDefaultRateLimit() 将其删除。

¥By default, DDPRateLimiter is configured with a single rule. This rule limits login attempts, new user creation, and password resets to 5 attempts every 10 seconds per connection. It can be removed by calling Accounts.removeDefaultRateLimit().

要使用 DDPRateLimiter 修改默认速率限制规则,请在终端中将 ddp-rate-limiter 包添加到你的项目中:

¥To use DDPRateLimiter for modifying the default rate-limiting rules, add the ddp-rate-limiter package to your project in your terminal:

bash
meteor add ddp-rate-limiter

DDPRateLimiter.addRule

Server only

Summary:

Add a rule that matches against a stream of events describing method or subscription attempts. Each event is an object with the following properties:

  • type: Either "method" or "subscription"
  • name: The name of the method or subscription being called
  • userId: The user ID attempting the method or subscription
  • connectionId: A string representing the user's DDP connection
  • clientAddress: The IP address of the user

Returns unique ruleId that can be passed to removeRule and setErrorMessageOnRule

Arguments:

Source code
NameTypeDescriptionRequired
matcherObject

Matchers specify which events are counted towards a rate limit. A matcher is an object that has a subset of the same properties as the event objects described above. Each value in a matcher object is one of the following:

  • a string: for the event to satisfy the matcher, this value must be equal to the value of the same property in the event object

  • a function: for the event to satisfy the matcher, the function must evaluate to true when passed the value of the same property in the event object

Here's how events are counted: Each event that satisfies the matcher's filter is mapped to a bucket. Buckets are uniquely determined by the event object's values for all properties present in both the matcher and event objects.

Yes
numRequestsnumber

number of requests allowed per time interval. Default = 10.

Yes
timeIntervalnumber

time interval in milliseconds after which rule's counters are reset. Default = 1000.

Yes
callbackfunction

function to be called after a rule is executed.

Yes

可以通过调用 DDPRateLimiter.addRule 添加自定义规则。速率限制器在每个方法和订阅调用时都会被调用。

¥Custom rules can be added by calling DDPRateLimiter.addRule. The rate limiter is called on every method and subscription invocation.

当存储桶超出规则的预定义容量时,将达到速率限制,此时将返回该输入的错误,直到重置存储桶。存储桶会在时间间隔结束后定期重置。

¥A rate limit is reached when a bucket has surpassed the rule's predefined capacity, at which point errors will be returned for that input until the buckets are reset. Buckets are regularly reset after the end of a time interval.

下面是定义规则并将其添加到 DDPRateLimiter 的示例:

¥Here's example of defining a rule and adding it into the DDPRateLimiter:

js
// Define a rule that matches login attempts by non-admin users.
const loginRule = {
  userId(userId) {
    const user = Meteor.users.findOne(userId);
    return user && user.type !== 'admin';
  },

  type: 'method',
  name: 'login'
};

// Add the rule, allowing up to 5 messages every 1000 milliseconds.
DDPRateLimiter.addRule(loginRule, 5, 1000);

DDPRateLimiter.removeRule

Server only

Summary:

Removes the specified rule from the rate limiter. If rule had hit a rate limit, that limit is removed as well.

Arguments:

Source code
NameTypeDescriptionRequired
idstring

'ruleId' returned from addRule

Yes
js
import { DDPRateLimiter } from "meteor/ddp-rate-limiter";

/** @returns boolean */
const result = DDPRateLimiter.removeRule();
  "id"
);

DDPRateLimiter.setErrorMessage

Server only

Summary:

Set error message text when method or subscription rate limit exceeded.

Arguments:

Source code
NameTypeDescriptionRequired
messagestring or function

Functions are passed in an object with a timeToReset field that specifies the number of milliseconds until the next method or subscription is allowed to run. The function must return a string of the error message.

Yes
js
import { DDPRateLimiter } from "meteor/ddp-rate-limiter";


const result = DDPRateLimiter.setErrorMessage();
  "message"
);

DDPRateLimiter.setErrorMessageOnRule

Server only

Summary:

Set error message text when method or subscription rate limit exceeded for a specific rule.

Arguments:

Source code
NameTypeDescriptionRequired
ruleIdstring

The ruleId returned from addRule

Yes
messagestring or function

Functions are passed in an object with a timeToReset field that specifies the number of milliseconds until the next method or subscription is allowed to run. The function must return a string of the error message.

Yes
js
import { DDPRateLimiter } from "meteor/ddp-rate-limiter";


const result = DDPRateLimiter.setErrorMessageOnRule();
  "ruleId",
"message",
);

允许开发者为每个规则指定自定义错误消息,而不是仅限于每个规则一个全局错误消息。它使哪些规则触发了哪些错误更加清晰,从而提供了更好的用户体验,并且为每个规则打开了 i18nable 错误消息的大门,而不是默认的英文错误消息。

¥Allows developers to specify custom error messages for each rule instead of being limited to one global error message for every rule. It adds some clarity to what rules triggered which errors, allowing for better UX and also opens the door for i18nable error messages per rule instead of the default English error message.

下面是带有自定义错误消息的示例:

¥Here is an example with a custom error message:

js
const setupGoogleAuthenticatorRule = {
  userId(userId) {
    const user = Meteor.users.findOne(userId);
    return user;
  },
  type: 'method',
  name: 'Users.setupGoogleAuthenticator',
};

// Add the rule, allowing up to 1 google auth setup message every 60 seconds
const ruleId = DDPRateLimiter.addRule(setupGoogleAuthenticatorRule, 1, 60000);
DDPRateLimiter.setErrorMessageOnRule(ruleId, function (data) {
  return `You have reached the maximum number of Google Authenticator attempts. Please try again in ${Math.ceil(data.timeToReset / 1000)} seconds.`;
});

或者更简单的方法:

¥Or a more simple approach:

js
const ruleId = DDPRateLimiter.addRule(setupGoogleAuthenticatorRule, 1, 60000);
DDPRateLimiter.setErrorMessageOnRule(ruleId, 'Example as a single string error message');