I’m attempting to implement basic authentication functionality for testing purposes. I’m testing via Postman, so before logging in, I make a GET request to /sanctum/csrf-cookie
. After that, I hit the /login
endpoint and am able to receive data (if this part $request->session()->regenerate();
is commented out). However, if I try to access a protected route, I receive an error. Despite following the documentation closely, I’m encountering an issue when a user attempts to sign in. I receive an error when $request->session()->regenerate();
this is not commented out:
"message": "Session store not set on request."
Here’s my bootstrap/app.php:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
using: function () {
Route::middleware('api')
->prefix('api')
->group(function () {
// routes/api.php is not included here
require base_path('routes/Api/V1/Auth/routes.php');
});
},
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->statefulApi();
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
Here’s my login:
public function login(object $request)
{
// Validate user credentials
if (!Auth::attempt($request->only(['username', 'password']))) {
return $this->failedRequest('', 'Invalid email address or password', 400);
}
// Regenerate the user's session to prevent session fixation
$request->session()->regenerate();
// Sign in user
Auth::login(Auth::user());
// Return data
return $this->successfullRequest(Auth::user(), 'User successfully logged in', 200);
}
My routes:
Route::group(['prefix' => 'v1/auth'], function () {
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
Route::post('logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
});
If I remove this part, I basically receive Unauthenticated message when I try to hit …/logout
$request->session()->regenerate();
sanctum.php -> stateful:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : '',
env('FRONTEND_URL') ? ',' . parse_url(env('FRONTEND_URL'), PHP_URL_HOST) : ''))),
my env file:
APP_URL=http://localhost:5000
FRONTEND_URL=http://localhost:3000
2
Answers
When testing your sanctum SPA authentication via Postman, make sure to include either the
Referer
orOrigin
header. Additionally, make sure the domain in the provided header matches a domain provided in thesanctum.stateful
config value (e.g. the domain used by yourAPP_URL
.env variable).These conditions are required for the
statefulApi()
middleware to enable the frontend middleware (including sessions).You can see the code here for determining if it is a frontend request that enables the frontend middleware.
Try using:
session()->regenerate()
In Laravel, the
session()
helper function is a shortcut to accessing the session instance.The session instance is globally available throughout the application, and it’s typically initialized during the bootstrapping process.