79830950

Date: 2025-11-26 16:52:18
Score: 0.5
Natty:
Report link

I finally noticed where I had a mistake

My session table didn't have an user_id because I was using UUID for my users, and session table wasn't properly configured for such UUID

Fixed session migration (notice that session table included in the create_users_table migration in laravel 12)

Schema::create('sessions', function (Blueprint $table) {
    $table->string('id')->primary();
    $table->foreignUuid('user_id')->nullable()->index();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->longText('payload');
    $table->integer('last_activity')->index();
});

EDIT
I also wanna to leave the important configuration places you need to check if you're getting errors


Config settings to check:

backend

1. Check your SPA (e.g. VueJS app) and API (e.g. Laravel) are on the same top level domain
For example:
api - localhost:8000
spa - localhost:5173
(notice: localhost = 127.0.0.1:8000 is a top-level domain)

2. Ensure to properly configure .env

APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:5173
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DOMAIN=localhost

3. In your bootstrap/app.php in the withMiddleware

$middleware->statefulApi(); 

4. Ensure config/cors.php is properly configured

Notice: If you don't have this file run: php artisan config:publish cors

    'paths' => ['*'], // optionally config this line (see usual config below)

    'allowed_methods' => ['*'], // EXAMINE THIS LINE 

    'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')], // v

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],
    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true, // AND EXAMINE THIS LINE (throws CORS error if false)

usually you can see this kind of config for paths in config/cors.php

'paths' => ['api/*', 'sanctum/csrf-cookie', '/login', '/logout'],

5. Session and SESSION_DRIVER
In your .env file:

If your SESSION_DRIVER=database (it's a default value and you don't need to touch it) check user_id is set after registration/login

Reminder:

- You don't need to call the /sanctum/csrf-cookie in logout, because after yout logged in or registered the frontend should already have the token
- Authentication routes (login, register, logout) should be in routes/api.php not routes/web.php


frontend

1. Check your axiosClient (if you're using one, or chec your axios are using proper settings)

Example of my src/axios.js

import axios from 'axios'
import router from '@/router/index.js'

const axiosClient = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // check how to configure this line below
  withCredentials: true, // THIS LINE IS IMPORTANT
  withXSRFToken: true, // THIS LINE IS ALSO IMPORTANT
})

axiosClient.interceptors.response.use( (response) =>{
  return response;
}, error => {
  if (error.response && error.response.status === 401){
    router.push({name: 'Login'})
  }

  throw error;
})

export default axiosClient

in your .env (notice: its a SPA's .env file, not an API's) check your have your API base URL, for example

VITE_API_BASE_URL=http://localhost:8000

2. Check your routes are sending the GET /sanctum/csrf-cookie request before **POST, PUT, PATCH, DELETE

example: login request

const form = reactive({
  email: '',
  password: '',
})

const errorMessage = ref('')

function submit() {
  // THIS LINE IS IMPORTANT
  axiosClient.get('/sanctum/csrf-cookie').then(response => {
    axiosClient.post('/login', form)
      .then(response => {
        router.push({name: 'Home'})
      })
      .catch(error => {
        errorMessage.value = error.response.data.message;
      })
  });
}

Reminder:

- You shouldn't call /sanctum/csrf-cookie for EVERY POST, PUT, PATCH, DELETE requests

Remember this: You only need to call the endpoint once at the start of the session.

Hope it'll provide clear understanding where you can find your error

Reasons:
  • Blacklisted phrase (1): thX
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Dmytro Shved