Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Laravel Middleware: Allow Admin Without Subscription?

Learn how to use Laravel middleware to bypass subscription checks for admin users while restricting access for others using Laravel Cashier.
Laravel middleware admin bypass skipping subscription gate with glowing Laravel logo and dramatic code effect Laravel middleware admin bypass skipping subscription gate with glowing Laravel logo and dramatic code effect
  • 🛡️ Laravel middleware can make sure only admin users bypass subscription checks and get into protected areas.
  • 🔄 Laravel Cashier has methods to handle trials, grace periods, and full subscription states well.
  • ⚙️ Custom middleware that mixes role and subscription logic helps with upkeep and security.
  • 🧩 Breaking access logic into separate middleware and policies makes systems easier to scale and test.
  • 🔐 Wrong role checks can cause big security problems; use safe ways like isAdmin().

Laravel Middleware: Allow Admin Without Subscription?

In a Laravel SaaS app that uses Laravel Cashier for billing, it is normal to limit features for users who have not paid. But many times, certain roles—like your admin users—should get full access no matter their subscription status. With Laravel middleware, you can choose which parts of your app’s routes to protect. This makes sure regular users must subscribe, but admins can skip those checks clearly and safely.


Understanding Laravel Middleware

Laravel middleware works as a middle step between a request and the code that handles it. Think of it as a gate that checks things. This setup works well for checking user authentication, roles, and subscriptions.

Middleware in Laravel can apply to all requests, or just to specific routes. It runs at different parts of the request. You set it up in app/Http/Kernel.php. Here are key stages:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • Global Middleware: Runs on every web request (for example, to remove extra spaces or change empty strings to nothing).
  • Route Middleware: Added to specific routes or groups of routes. This gives you exact control.

Here’s an example idea of how a web request works:

  1. A user asks for something from a specific web address.
  2. Laravel sends the request to the right place.
  3. Middleware runs:
    • It checks who the user is.
    • It checks the subscription.
    • It checks the user’s role.
  4. If all checks pass, the controller code runs.
  5. A response goes back. It might go through more middleware (for example, to record the response or handle CORS).

Why use middleware for access control?

  • It puts the checking logic in one place, away from controllers.
  • You can use it for many different web addresses.
  • It makes your app predictable and safe.

📚 Read more in Laravel’s documentation


Conditional Middleware Logic: The Laravel Way

Middleware is very good when decisions depend on what a user is, like their roles or subscriptions. Conditional middleware logic means using if-else statements inside your middleware. This treats different users in different ways based on rules you set.

Common Conditional Scenarios

  • Admin users manage the back-end no matter their subscription status.
  • Users who are not admins need an active subscription to use special features.
  • Users on a trial plan can skip subscription checks for a short time.
  • Users in a grace period, who have canceled but still have active access.

Middleware that is set up well handles these cases simply. It follows the correct order:

  1. Check that the user is logged in.
  2. See if the user’s role lets them skip subscription checks.
  3. Check the subscription status using Laravel Cashier helpers.

Keeping things separate makes each middleware clean, easy to build with, and reusable.


Using Laravel Cashier for Subscription Management

Laravel Cashier gives you a simple way to use Stripe and Braintree. It handles things like making subscriptions, changing plans, and checking payment status.

Here are some of the most helpful methods it offers:

$user->subscribed('default');
$user->onTrial('default');
$user->subscription('default')->onGracePeriod();
$user->subscription('default')->cancelled();

Using these methods, you can:

✅ Figure out if access should be given
✅ Decide what message or screen to show (for example, “Your trial has ended”)
✅ Send users to upgrade or billing pages

Cashier States to Know

Method What it means
subscribed('default') Says true if the user has an active subscription
onTrial('default') true if the user is in the trial period
onGracePeriod() true if the user’s subscription is canceled but still active
cancelled() Shows a subscription was canceled (after the grace period)

💡 Cashier simplifies this logic. It makes it easier to manage SaaS billing without writing direct Stripe API calls.

📚 Official Cashier Docs


Finding Admin Users Correctly

Before skipping subscription checks, you must know for sure who your admins are. Just writing "user_id === 1" or checking an email like admin@example.com can cause mistakes and security risks.

Better Admin Checks

  1. Add a method to the User model:
public function isAdmin()
{
    return $this->role === 'admin'; // Or use a list of options/settings for roles
}
  1. Use Authorization Gates or Policies, for example:
Gate::define('admin-only', function ($user) {
    return $user->hasRole('admin');
});
  1. Use Spatie Permissions Package:

    • Give roles using php artisan permission:create-role admin
    • Use hasRole() or hasPermissionTo()
  2. Use a list of options or config-driven roles for easier upkeep.

These ways make sure admin checks are always the same and safe in your app.

📚 Laravel Authorization Docs


Making Middleware That Knows Roles

Build a middleware that checks both isAdmin() and Cashier subscription status.

Step 1: Make a Middleware

php artisan make:middleware EnsureUserIsSubscribed

Step 2: Change the Middleware Logic

public function handle($request, Closure $next)
{
    $user = auth()->user();

    if ($user->isAdmin()) {
        return $next($request);
    }

    if (
        $user->subscribed('default') ||
        $user->onTrial('default') ||
        $user->subscription('default')?->onGracePeriod()
    ) {
        return $next($request);
    }

    return redirect()->route('subscription.plans');
}

🎯 Main points:

  • isAdmin() stops all other checks right away.
  • Users in a grace period or on trial are allowed.
  • Users without a subscription are sent to the right place.

Remember to use ?-> to prevent errors if subscription('default') gives no result.


Route Usage: Applying Middleware Simply

Once you have defined the middleware, add it to your Kernel file.

// app/Http/Kernel.php
protected $routeMiddleware = [
    'verified_subscriber' => \App\Http\Middleware\EnsureUserIsSubscribed::class,
];

Now add it to routes:

Route::middleware(['auth', 'verified_subscriber'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
});

You can also add it right to specific routes:

Route::get('/settings', [SettingsController::class, 'index'])
    ->middleware(['auth', 'verified_subscriber']);

Handling Special Cases: Trials, Grace Periods, Cancels

SaaS billing has more than just "active" and "inactive" users. There are also trial users, users in grace periods, and users with recently canceled subscriptions. Laravel Cashier makes it easy to handle these states.

✔️ Add trial and grace logic:

if (
    $user->isAdmin() ||
    $user->subscribed('default') ||
    $user->onTrial('default') ||
    $user->subscription('default')->onGracePeriod()
) {
    return $next($request);
}

This keeps you from accidentally blocking a user who:

  • Just started a free trial.
  • Is still in an acceptable period after canceling.
  • Has admin rights but no subscription.

🧠 Thinking about this helps avoid support emails and upset users.


Middleware Setup and Layering Best Practices

Do not make one large middleware that tries to do everything. Keep different tasks separate for easier upkeep.

🏗️ Suggested Middleware Layers:

  1. auth – Checks that the user is logged in.
  2. verified – Makes sure email is confirmed if needed.
  3. role:admin – For parts that only admins can see.
  4. subscribed – Your custom middleware to manage subscription rules.

🧩 Use them as needed:

Route::middleware(['auth', 'verified', 'subscribed'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
});

📛 Do not do this:

// Controller that does all checks inside
if (!auth()->user()->hasRole('admin') && !auth()->user()->subscribed()) {
    abort(403);
}

Instead, let middleware manage access. Keep your controllers focused on business tasks.


Testing and Debugging Custom Middleware

Middleware works well only if you test it. With Laravel's built-in testing tools (PHPUnit), make sure your access rules work in real situations.

✅ Use Feature Tests

public function test_admin_bypasses_subscription()
{
    $admin = User::factory()->create(['role' => 'admin']);

    $this->actingAs($admin)
         ->get('/dashboard')
         ->assertOk();
}

public function test_regular_user_is_redirected_without_subscription()
{
    $user = User::factory()->create();

    $this->actingAs($user)
         ->get('/dashboard')
         ->assertRedirect('/subscription/plans');
}

🧪 Use Laravel’s Subscription Testing Helpers

With Cashier, you can set up fake billing states directly:

$user->trial_ends_at = now()->addDays(7);
// or
$user->subscriptions()->create([...]);

Always test these:

  • User not logged in.
  • Admin user.
  • Trial user.
  • Grace period user.
  • User with a fully canceled subscription.

Automated tests help stop mistakes in unusual situations.


Security Considerations

Controlling access is a big part of security. Do not take shortcuts that could cause problems.

🚫 Avoid:

  • Using user IDs or emails for admin logic.
  • Skipping subscription checks by hand in controllers.

✅ Use:

  • Clear isAdmin() checks.
  • Layered middleware logic.
  • Safe role management through trusted packages.
  • Always check subscription status unless you have a specific reason not to.

📚 Important: OWASP A05 – Security Misconfiguration


Other Ways to Do It: Policy-Based Checks vs Middleware

For some cases, Laravel’s authorization policies might be better than middleware.

When to use Policies

  • Permissions change based on data (for example, Company A vs Company B).
  • Different parts of your app need different access rules.
  • You need to add Gate/Policy checks to specific model methods (for example, update() or view()).

👟 Use both for the best results:

  • Use middleware for general access control.
  • Use policies for checks specific to a resource (for example, permissions for each document, team, or workspace).

📚 More on Authorization Policies


Recap: Simple, Scalable Middleware Design for SaaS Apps

A good middleware setup helps you:

✅ Make subscription rules apply everywhere.
✅ Let admins skip checks safely.
✅ Handle trial and grace periods well.
✅ Keep access rules separate from other business code.
✅ Write tests that cover real situations.

For SaaS platforms made with Laravel, understanding middleware and Laravel Cashier is important for better security and user experiences.


Devsolus Tips: Developer Learnings & Future-proofing

🛠️ Build for now. Plan for growth.

  • Always use isAdmin() instead of fixed checks.
  • Keep middleware small and focused on one task.
  • Use Laravel route groups for a clear structure.
  • Stay up to date with new Laravel Cashier releases.
  • Write down how you handle unusual situations for your team or in your documents.

💬 Want more Laravel SaaS examples? Follow Devsolus for detailed articles on Laravel tools, multi-tenant plans, and Laravel Cashier setups.


Citations

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading