Milind Daraniya

Securing Laravel REST APIs: Rate Limiting and Token Expiry

Published June 1st, 2026 4 min read

Why API Security Matters for Your Business

When you build a web application, especially one with a ReactJS frontend and a Laravel backend, your APIs are the main entry point. If you do not secure them, malicious bots can spam your login endpoints, scrape your data, or bring your server down with DDoS attacks. In my 9+ years of PHP development, I have seen many production servers crash just because there was no rate limiting on a public API endpoint.

Setting Up Rate Limiting in Laravel

Laravel makes rate limiting very simple. By default, Laravel uses a middleware called throttle. You can define your rate limiters in the boot method of your App\Providers\RouteServiceProvider.php file (or AppServiceProvider depending on your Laravel version).

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('api', function (Request $request) {
    return Limit::perMinute(60)->by($request->user()?->id ?? $request->ip());
});

This configuration allows 60 requests per minute per authenticated user, or per IP address for guests. It protects your database from getting overloaded by too many queries.

Customizing Rate Limits for Sensitive Routes

Not all endpoints are the same. Your login or password-reset endpoints need stricter limits. You can create a custom rate limiter for them:

RateLimiter::for('login', function (Request $request) {
    return Limit::perMinute(5)->by($request->ip());
});

Apply this to your login route in routes/api.php:

Route::post('/login', [AuthController::class, 'login'])->middleware('throttle:login');

Managing Token Expiry with Laravel Sanctum

Laravel Sanctum is the easiest way to issue API tokens for SPAs and mobile apps. However, issuing tokens that never expire is a big security risk. If someone steals a token, they have permanent access to your user's data.

Setting Token Expiration

To set an expiration time for Sanctum tokens, open your config/sanctum.php file and look for the expiration key. By default, it is set to null (never expires). Change it to a reasonable value in minutes, like 24 hours (1440 minutes):

'expiration' => 1440,

Once this is set, any token older than 24 hours will be rejected automatically by the auth:sanctum middleware.

Handling Expired Tokens in ReactJS

When a token expires, Laravel will return a 401 Unauthorized status code. Your frontend ReactJS application should handle this gracefully. You can use an Axios interceptor to catch 401 errors, clear the local storage, and redirect the user to the login page:

axios.interceptors.response.use(
    response => response,
    error => {
        if (error.response && error.response.status === 401) {
            localStorage.removeItem('api_token');
            window.location.href = '/login';
        }
        return Promise.reject(error);
    }
);

Conclusion

Securing your REST APIs is not a one-time task but a continuous practice. By combining Laravel's built-in rate limiting with Sanctum's token expiration, you protect your application from abuse and keep your hosting costs low. If you are a founder or business owner, investing in these security practices early will save you from downtime and data breaches later.

Common Questions

What is the default rate limit in Laravel?

Laravel does not enforce a strict default rate limit unless you apply the throttle middleware to your routes. You can easily define custom rate limits in your RouteServiceProvider.

How does Laravel Sanctum check for token expiration?

Sanctum checks the 'expiration' value in your config/sanctum.php file. If the token's creation timestamp plus the expiration time is in the past, the request is rejected with a 401 Unauthorized status.

Can I set different rate limits for different users?

Yes, inside the RateLimiter definition, you can check the authenticated user's properties (like subscription plan or role) and return different Limit values dynamically.