Problem
I am struggling with annoying 419 error trying to logout. The login and register are working fine. My api and spa are on the same top-level domain, but different ports
api - localhost:8000
spa (vue) - localhost:5173
After hours of debugging and changing the different settings I still get the 419
Code
backend:
env
APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:5173
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DOMAIN=localhost
bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
apiPrefix: 'api/v1',
)
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'role' => RoleMiddleware::class,
]);
$middleware->api(prepend: [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
]);
$middleware->statefulApi();
})
->withExceptions(function (Exceptions $exceptions): void {
//
})->create();
cors
'paths' => ['*'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
sanctum
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,localhost:5173,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort(),
// Sanctum::currentRequestHost(),
))),
authentication routes in routes/web.php
Route::post('login', LoginController::class);
Route::post('register', RegisterController::class);
Route::post('logout', LogoutController::class);
LoginController.php
public function __invoke(LoginRequest $request)
{
if (Auth::attempt($request->validated())){
$request->session()->regenerate();
return (new UserResource(Auth::user()));
}else{
return response()->json([
'message' => 'The provided credentials are incorrect'
], 422);
}
}
LogoutController.php
public function __invoke(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return response()->json([
'message' => 'Logged out'
]);
}
frontend:
axios.js
import axios from 'axios'
import router from '@/router/index.js'
const axiosClient = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
withCredentials: true,
withXSRFToken: true,
})
axiosClient.interceptors.response.use( (response) =>{
return response;
}, error => {
if (error.response && error.response.status === 401){
router.push({name: 'Login'})
}
throw error;
})
export default axiosClient
env
VITE_API_BASE_URL=http://localhost:8000
logout function
function logout() {
axiosClient.post('/logout')
.then((response) => {
router.push({name: 'Login'})
})
}
login function
const data = ref({
email: '',
password: '',
})
const errorMessage = ref('')
function submit() {
axiosClient.get('/sanctum/csrf-cookie').then(response => {
axiosClient.post('/login', data.value)
.then(response => {
router.push({name: 'Home'})
})
.catch(error => {
console.log(error.response)
errorMessage.value = error.response.data.message;
})
});
}
How the process to get 419 (unknown status) looks like:
- Log in (success preflight request & actual login request)
- success logout preflight request
- see the 419 (unknown status) error in actual logout request
- check cookies are set in the logout request(Cookie & X-XSRF-TOKEN headers are set)
Would be grateful for your help
Best regards