Laravel 11 Session Error When Building Jira Cloud Connect Application

I’m working on creating a Jira Cloud Connect application using Laravel 11, but I keep running into a session error during the installation process.

The specific error message I’m getting is:

local.ERROR: Session store not set on request

This happens when Jira tries to install my connect app. I’m pretty new to Laravel 11 so I might be missing something obvious.

Here’s my setup controller (SetupHandler.php):

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Installation;
use Illuminate\Support\Facades\Log;

class SetupHandler extends Controller
{
    public function handleInstall(Request $request)
    {
        $appKey = $request->input('clientKey');
        $jiraUrl = $request->input('baseUrl');
        
        Log::info('New installation attempt', $request->all());
        
        $installation = new Installation();
        $installation->app_key = $appKey;
        $installation->jira_url = $jiraUrl;
        
        try {
            $installation->save();
        } catch (\Exception $error) {
            Log::error('Installation save failed: ' . $error->getMessage());
            return response()->json(['result' => 'failed', 'error' => 'Could not save installation'], 500);
        }
        
        return response()->json(['result' => 'success']);
    }
}

My routes file (web.php):

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SetupHandler;
use App\Http\Middleware\VerifyCsrfToken;

Route::get('/', function () {
    return view('welcome');
});

Route::post('/setup', [SetupHandler::class, 'handleInstall'])
    ->middleware(VerifyCsrfToken::class);

CSRF middleware configuration:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    protected $except = [
        '/app/public/setup',
    ];
}

My ngrok tunnel shows this error: POST /app/public/setup 419 unknown status

What am I doing wrong here? Any help would be great since I’m still learning Laravel 11.

Your session error is occurring because Jira’s webhook requests do not carry Laravel session data, which is expected for external API calls. The main issue lies in your middleware configuration; you’re excluding /app/public/setup, but your actual route is /setup. Laravel treats these as different paths, so CSRF protection remains active.

Adjust your exclusion to just '/setup' and remove the explicit middleware application from your route. Ideally, relocate this endpoint to api.php routes, as webhook handlers should not rely on web middleware. I’ve created several Atlassian Connect apps, and API routes are better suited for this purpose due to their stateless nature.

Additionally, ensure your atlassian-connect.json descriptor points to the correct URL structure that aligns with your route configuration.

The issue seems to be with your CSRF token configuration and middleware setup. You’re getting a 419 error which typically indicates CSRF token mismatch, and the session error suggests Laravel can’t access the session store when Jira makes the webhook call. First, your CSRF exclusion path doesn’t match your actual route. You have /app/public/setup in the exclusion but your route is just /setup. The exclusion should be '/setup' without the /app/public part since that’s handled by your web server configuration. Second, you’re explicitly applying the CSRF middleware to a route that should be excluded from CSRF protection. Remove the ->middleware(VerifyCsrfToken::class) from your route definition entirely. External webhooks like Jira’s installation callback can’t provide CSRF tokens. Also consider moving this route to your api.php routes file instead of web.php since it’s essentially an API endpoint that doesn’t need web middleware like sessions and CSRF protection. API routes are stateless by default which is more appropriate for webhook handlers.

looks like your mixing up csrf protection - you cant have /setup route excluded in middleware but then still apply VerifyCsrfToken to the same route. thats contradictory. remove the middleware from route definition and fix the exclusion path to just '/setup' not the full ngrok path.