I have my API that run on this url: https://example.com, and my vue.js app which runs on this: https://app.example.com. So I configured as the following the .env:
SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=https://app.example.com
the axios configuration contains the following:
import axios from 'axios'
const server = axios.create({
baseURL: 'https://example.com'
})
server.defaults.withCredentials = true
server.defaults.withXSRFToken = true
within the file sanctum.php I setted as guard api:
'guard' => ['api']
and within kernel.php I did:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
I also added:
\Illuminate\Session\Middleware\StartSession::class,
within $middleware group.
The application flow is the following: when I press the login button I sent a request to:
/sanctum/csrf-cookie
which return 204 and set the cookie, then I perform the login request that return 204, so far everything seems good. At the end, I try to sent a GET request to /user that is protected as the following:
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [UserController::class, 'index']);
});
but I get unauthorized. I spend the whole day try to figur out, tried a lot of solutions but no one has worked.
I get the same result on postman.
UPDATE
config/sanctum.php
<?php
use Laravel\Sanctum\Sanctum;
return [
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
'guard' => ['web'],
'expiration' => null,
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
],
];
config.cors.php
<?php
return [
'paths' => [
'api/*',
'login',
'logout',
'register',
'sanctum/csrf-cookie'
],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
config/session.php
<?php
use Illuminate\Support\Str;
return [
'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION'),
'table' => 'sessions',
'store' => env('SESSION_STORE'),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN'),
'secure' => env('SESSION_SECURE_COOKIE'),
'http_only' => true,
'same_site' => 'lax',
'partitioned' => false,
];
config/auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_reset_tokens',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
.env
SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=https://app.example.com
Notice that both domains are https registered with letsencrypt, I just hided them for privacy reason.
I think you missed setting the
supports_credentialsoption totrueinconfig/cors.php