最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

laravel - Rate Limiting Rest API in Statamic CMS - Stack Overflow

programmeradmin0浏览0评论

I've been stuck on this for far too long. I am no expert in Laravel. I am currently using Statamic CMS as a headless CMS by which I grab data via the rest API. The default rate limit on these endpoints are 60, I want to amend this value. I am really struggling to get anything to work however.

I have created a RouteServiceProvider.php which looks like:

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use App\Http\Middleware\ThrottleRequests;

class RouteServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->configureRateLimiting();

        parent::boot();
    }

    protected function configureRateLimiting()
    {
        Log::channel('single')->info('configureRateLimiting function fired');
        RateLimiter::for('api', function (Request $request) {
            Log::channel('single')->info('rate limit fired');
            // Authenticated users: 1 requests/minute, else 1 requests/minute
            return $request->user()
                ? Limit::perMinute(1)->by($request->user()->id)
                : Limit::perMinute(1)->by($request->ip());
        });
    }

I register this new file in the bootstrap/providers.php file:

<?php

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
];

then finally in the routes/web.php file i have:

Route::middleware(['throttle:api'])
        ->prefix(config('statamic.api.route', 'api'))
        ->group(function () {
            Log::info('Statamic API middleware applied');
            
            // Get the original request and pass it through
            Route::any('{any}', function($any) {

                Log::info('API Request Details', [
                    'path' => request()->path(),
                    'method' => request()->method(),
                    'parameters' => request()->all()
                ]);
                return response()->json([
                        'message' => 'Statamic API request handled with rate limiting.'
                ]);
              
            })->where('any', '.*');
        });

So the above actually works and logs everything as I would expect. If I attempt to remove the

return response()->json([
   'message' => 'Statamic API request handled with rate limiting.'
]);

as I would just like the original API data to be returned it just hits the rate limit on every call. I have tried: return app()->handle(request()); but this does not work. I can't for the life of me work out how to simply allow the rate limiter to wrap around the api endpoints and continue to return the data until the point they hit the rate limit.

I'm sure I must be missing something simple as the Docs make it sound trivial: /rest-api#rate-limiting

Any pointers would be hugely appreciated.

I've been stuck on this for far too long. I am no expert in Laravel. I am currently using Statamic CMS as a headless CMS by which I grab data via the rest API. The default rate limit on these endpoints are 60, I want to amend this value. I am really struggling to get anything to work however.

I have created a RouteServiceProvider.php which looks like:

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use App\Http\Middleware\ThrottleRequests;

class RouteServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->configureRateLimiting();

        parent::boot();
    }

    protected function configureRateLimiting()
    {
        Log::channel('single')->info('configureRateLimiting function fired');
        RateLimiter::for('api', function (Request $request) {
            Log::channel('single')->info('rate limit fired');
            // Authenticated users: 1 requests/minute, else 1 requests/minute
            return $request->user()
                ? Limit::perMinute(1)->by($request->user()->id)
                : Limit::perMinute(1)->by($request->ip());
        });
    }

I register this new file in the bootstrap/providers.php file:

<?php

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
];

then finally in the routes/web.php file i have:

Route::middleware(['throttle:api'])
        ->prefix(config('statamic.api.route', 'api'))
        ->group(function () {
            Log::info('Statamic API middleware applied');
            
            // Get the original request and pass it through
            Route::any('{any}', function($any) {

                Log::info('API Request Details', [
                    'path' => request()->path(),
                    'method' => request()->method(),
                    'parameters' => request()->all()
                ]);
                return response()->json([
                        'message' => 'Statamic API request handled with rate limiting.'
                ]);
              
            })->where('any', '.*');
        });

So the above actually works and logs everything as I would expect. If I attempt to remove the

return response()->json([
   'message' => 'Statamic API request handled with rate limiting.'
]);

as I would just like the original API data to be returned it just hits the rate limit on every call. I have tried: return app()->handle(request()); but this does not work. I can't for the life of me work out how to simply allow the rate limiter to wrap around the api endpoints and continue to return the data until the point they hit the rate limit.

I'm sure I must be missing something simple as the Docs make it sound trivial: https://statamic.dev/rest-api#rate-limiting

Any pointers would be hugely appreciated.

Share Improve this question asked Feb 4 at 10:44 wizzer711wizzer711 214 bronze badges 2
  • there are many available solution in the net for api throttle in laravel 11, here is one apiacademy.treblle/laravel-api-course/rate-limiting – N69S Commented Feb 4 at 11:03
  • 1 You're effectively applying throttling twice. When you return a custom JSON, the middleware runs once. But calling app()->handle(request()) dispatches the same request again (with throttle), so it immediately hits the limit. – A. El-zahaby Commented Feb 4 at 23:21
Add a comment  | 

1 Answer 1

Reset to default 0

You might be better asking in the Statamic Discord or on GitHub Discussions. The Statamic Community isn't very active here on StackOverflow.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>