Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

muuucho's avatar
Level 11

403 on live server, not on local

All of a sudden my live server starts to throw a 403, but only when calling a single route. Everything else works fine. Log is empty.

Link: <a href="{{ route('invoices.edit', $invoice) }}">Edit</a>

Route (I removed a middleware, still 403): Route::get('invoices/{invoice}', \App\Livewire\Invoices\Form::class)->name('invoices.edit');

I've put die('here') in the mount() and that shows on my local machine but on my live server it's still a 403. Any idea how I can narrow this problem down?

I'm on PHP 8.2, Laravel 11.20.0 Livewire 3

0 likes
5 replies
tykus's avatar
  • Is that the only Route defined for 'invoices/{invoice}' URI; e.g. do you have a invoices.show route also?
  • Do you have a Policy registered for the Invoice model?
  • I removed a middleware - what middleware? Show us the relevant code.
1 like
muuucho's avatar
Level 11

@tykus Thanks. I have invoices routes and the other ones are working:

Route::get('invoices', \App\Livewire\Invoices\All::class)->name('invoices.all');
    Route::get('invoices/create', \App\Livewire\Invoices\Form::class)->name('invoices.create');
    Route::get('invoices/{invoice}', \App\Livewire\Invoices\Form::class)->name('invoices.edit');
    Route::get('invoice/{id}', \App\Livewire\Invoices\Show::class)->name('invoices.show');

I have no policy registered.

Middelware, or Gates in AppServiceProvider:

public function boot()
    {
        // Should return TRUE or FALSE
        Gate::define('manage_upload', function (User $user){
            return $user->manage_upload == 1;
        });
        Gate::define('manage_invoice', function (User $user){
            return $user->manage_invoice == 1;
        });
        Gate::define('manage_payment', function (User $user){
            return $user->manage_payment == 1;
        });
        Gate::define('manage_attest_rule', function (User $user){
            return $user->manage_attest_rule == 1;
        });
        Gate::define('is_admin', function (User $user){
            return $user->is_admin == 1;
        });
    }
muuucho's avatar
Level 11

UPDATE: Everything is working, I put back the middleware restriction. I don't know why, but it's working! Scary though.

@tykus Actually, it is actually the middleware middleware('can:manage_invoices') that cuases the 403. I realized that when I removed it AND cleared the route cache. So, when I use it to retrict the edit route, the debugbar on the 403 page says:

This action is unauthorized.
vendor/laravel/framework/src/Illuminate/Auth/Access/Response.php#152
public function authorize()
    {
        if ($this->denied()) {
            throw (new AuthorizationException($this->message(), $this->code()))
                ->setResponse($this)
                ->withStatus($this->status);
      

and the first array (out of 51) below:

 0 => array:5 [▼
    "file" => "vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php"
    "line" => 393
    "function" => "authorize"
    "class" => "Illuminate\Auth\Access\Response"
    "type" => "->"
  ]

The restricition is ->middleware('can:manage_invoices')

One more thing: I had a strange error on the invoices.all route. I t said:

SQLSTATE[HY000] [1130] Host 'localhost' is not allowed to connect to this MariaDB server

When I refreshed the page everything was back to normal. But I was thinking that if the gate can't reach the database, it mightreturn false and then the 403 is thrown. So, maybe som sort of db issue?

tykus's avatar
tykus
Best Answer
Level 104

@muuucho if you are not signed in, you will not have a User instance so the Gate will deny access.

Also, there is no way to get to the invoices.show Route, because the edit action will always be matched first.

Route::get('invoices/{invoice}', \App\Livewire\Invoices\Form::class)->name('invoices.edit');
Route::get('invoice/{id}', \App\Livewire\Invoices\Show::class)->name('invoices.show');

By convention, the URL segments for the edit action is invoices/{invoice}/edit'

1 like
LaryAI's avatar
Level 58

A 403 Forbidden error typically indicates that the server understands the request but refuses to authorize it. Here are some steps to help you troubleshoot and resolve the issue:

  1. File Permissions: Ensure that the file and directory permissions on your live server are correctly set. The web server needs to have the appropriate permissions to access the files. For Laravel, the storage and bootstrap/cache directories should be writable by the web server.

    sudo chown -R www-data:www-data /path-to-your-project/storage
    sudo chown -R www-data:www-data /path-to-your-project/bootstrap/cache
    sudo chmod -R 775 /path-to-your-project/storage
    sudo chmod -R 775 /path-to-your-project/bootstrap/cache
    
  2. Server Configuration: Check your server configuration (e.g., Apache or Nginx) to ensure there are no rules blocking access to the route. For example, in Nginx, make sure there are no deny directives affecting the route.

  3. .htaccess Rules: If you are using Apache, check your .htaccess file for any rules that might be causing the 403 error.

  4. Route Caching: If you have recently made changes to your routes, try clearing the route cache.

    php artisan route:clear
    
  5. Middleware and Policies: Double-check any middleware or policies that might be applied to the route. Even though you mentioned removing middleware, ensure there are no other authorization checks in place.

  6. Server Logs: Since your application logs are empty, check the server logs (e.g., Apache or Nginx error logs) for more information about the 403 error.

  7. Livewire Component: Ensure that the Livewire component is correctly set up and there are no issues with the component itself. Sometimes, issues within the component can cause unexpected behavior.

  8. CSRF Token: Ensure that the CSRF token is correctly included in your forms if applicable. Although this is more common with POST requests, it's good to check.

Here is a checklist to help you narrow down the problem:

  • Verify file and directory permissions.
  • Check server configuration for any restrictive rules.
  • Review .htaccess for any deny rules.
  • Clear route cache.
  • Double-check middleware and policies.
  • Review server logs for more details.
  • Ensure the Livewire component is correctly set up.
  • Verify CSRF token inclusion if applicable.

If none of these steps resolve the issue, you might want to try creating a new route and Livewire component to see if the problem persists. This can help determine if the issue is specific to the current route/component or a broader configuration issue.

// Example of a new route and component for testing
Route::get('test-invoice/{invoice}', \App\Livewire\Invoices\TestForm::class)->name('invoices.test');

// TestForm Livewire component
namespace App\Livewire\Invoices;

use Livewire\Component;

class TestForm extends Component
{
    public $invoice;

    public function mount($invoice)
    {
        $this->invoice = $invoice;
    }

    public function render()
    {
        return view('livewire.invoices.test-form');
    }
}

By following these steps, you should be able to identify and resolve the cause of the 403 error on your live server.

Please or to participate in this conversation.