Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request to support rate limit mechanism #4044

Closed
JohnNiang opened this issue Jun 7, 2023 · 9 comments · Fixed by #4062
Closed

Request to support rate limit mechanism #4044

JohnNiang opened this issue Jun 7, 2023 · 9 comments · Fixed by #4062
Assignees
Labels
area/core Issues or PRs related to the Halo Core kind/feature Categorizes issue or PR as related to a new feature.
Milestone

Comments

@JohnNiang
Copy link
Member

JohnNiang commented Jun 7, 2023

Your current Halo version

2.7.0-SNAPSHOT

Describe this feature

Currently, everyone can request all APIs without limit, such as login and comments APIs, which is very dangerous and provides opportunity for brute-force attack and injecting large amounts of invalid data.

Learn more about RateLimit, please refer to

Additional information

/kind feature
/area core

@f2c-ci-robot f2c-ci-robot bot added kind/feature Categorizes issue or PR as related to a new feature. area/core Issues or PRs related to the Halo Core labels Jun 7, 2023
@guqing
Copy link
Member

guqing commented Jun 7, 2023

目前 halo 本身就是引入了google guava 的可以直接使用 guava 提供的 RateLimiter https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/RateLimiter.java

@JackyLiang522
Copy link
Contributor

/assign

@JackyLiang522
Copy link
Contributor

JackyLiang522 commented Jun 7, 2023

Hi! I have tried adding a login rate limiter with google guava. Does it look correct?
https://github.com/halo-dev/halo/compare/main...JustinLiang522:issue4044?expand=1

@JohnNiang
Copy link
Member Author

Hi! I have tried adding a login rate limiter with google guava. Does it look correct? https://github.com/halo-dev/halo/compare/main...JustinLiang522:issue4044?expand=1

Thanks for your investigation!

But I have three questions to the implementation:

  1. Is the limiter blocking operation?
    If it it, the operation may block the non-blocking threads to serve requests. Please refer to https://projectreactor.io/docs/core/release/reference/#_blocking_can_be_wasteful.
  2. Should we distinguish IP address in the rate limiter?
  3. Finally, what if we need to deal with other APIs?

Would love to hear your feedback.

@JackyLiang522
Copy link
Contributor

JackyLiang522 commented Jun 8, 2023

Thank you for your advice!

Based on the implementation of Guava Rate Limiter, it is not a blocking operation. In the codes, the tryAcquire is called with timeout=0, so it will not block the thread.

For question 2 and 3. I think we can define a ApiRateLimiter class like below, which includes an object to map users' IP addresses to rate limiters. This class can be used whenever needed.

public class ApiRateLimiter {
    private final Map<String, RateLimiter> rateLimiterMap = new HashMap<>();
    private final double rate;

    public ApiRateLimiter(double rate) {
        this.rate = rate;
    }

    public boolean tryAcquire(String clientIpAddress) {
        if (rateLimiterMap.containsKey(clientIpAddress)) {
            return rateLimiterMap.get(clientIpAddress).tryAcquire();
        } else {
            var rateLimiter = RateLimiter.create(rate);
            rateLimiterMap.put(clientIpAddress, rateLimiter);
            return rateLimiter.tryAcquire();
        }
    }
}

@JohnNiang
Copy link
Member Author

I also made a simple implementation about Rate Limit mechanism using https://github.com/resilience4j/resilience4j. Please see https://github.com/halo-dev/halo/compare/main...JohnNiang:halo:feat/rate-limit?expand=1 for more.

Why should I choose the resilience4j?

  1. It integrates with Spring Boot 3, which can let us configure Rate Limit in application.yaml instead of changing code directly.
  2. It provides a module with custom Spring Reactor operators. So that we can integrate it into Halo easily.
  3. We can easily can override the in-memory RateLimiterRegistryStore by a custom implementation.
  4. It allows us use Ehcache, Caffeine, Redisson, Hazelcast, Ignite or other JCache implementation as Cache Manager for the RateLimiterRegistryStore.

@JackyLiang522
Copy link
Contributor

I also made a simple implementation about Rate Limit mechanism using https://github.com/resilience4j/resilience4j. Please see https://github.com/halo-dev/halo/compare/main...JohnNiang:halo:feat/rate-limit?expand=1 for more.

Your code looks complete and well-structured. I am not sure if there is still any part that I can contribute to at this point. I would be happy to help in any way I can.

@guqing
Copy link
Member

guqing commented Jun 9, 2023

/milestone 2.7.x

@f2c-ci-robot f2c-ci-robot bot added this to the 2.7.x milestone Jun 9, 2023
@JohnNiang
Copy link
Member Author

JohnNiang commented Jun 9, 2023

Your code looks complete and well-structured. I am not sure if there is still any part that I can contribute to at this point. I would be happy to help in any way I can.

Hi @JustinLiang522 , I will try to implement rate limit for login endpoint, and you can have a try on comment endpoint.

/assign

f2c-ci-robot bot pushed a commit that referenced this issue Jun 16, 2023
#### What type of PR is this?

/kind feature
/area core

#### What this PR does / why we need it:

This PR introduces https://github.com/resilience4j/resilience4j to archive the feature. The login endpoint has limited login failures at a rate of 3 per minute.

See #4044 for more.

#### Which issue(s) this PR fixes:

Fixes #4044

#### Special notes for your reviewer:

1. Start Halo.
2. Try to login with incorrect credential 4 times
3. Check the response.

#### Does this PR introduce a user-facing change?

```release-note
增加登录失败次数限制功能
```
@ruibaby ruibaby modified the milestones: 2.7.x, 2.7.0 Jun 19, 2023
f2c-ci-robot bot pushed a commit that referenced this issue Jun 26, 2023
#### What type of PR is this?

/kind feature
/kind core

#### What this PR does / why we need it:

This PR limited comment creation at a rate of 10 per minute.

See #4044 for more.

#### Special notes for your reviewer:
1. Start Halo.
2. Create 11 new comments
3. Check the response.

#### Does this PR introduce a user-facing change?

```release-note
增加发表评论频率限制功能
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core Issues or PRs related to the Halo Core kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants