skip to Main Content

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' => [
        LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class,
        IlluminateRoutingMiddlewareThrottleRequests::class.':api',
        IlluminateRoutingMiddlewareSubstituteBindings::class,
    ],

I also added:

IlluminateSessionMiddlewareStartSession::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 LaravelSanctumSanctum;

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' => LaravelSanctumHttpMiddlewareAuthenticateSession::class,
        'encrypt_cookies' => AppHttpMiddlewareEncryptCookies::class,
        'verify_csrf_token' => AppHttpMiddlewareVerifyCsrfToken::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 IlluminateSupportStr;

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' => AppModelsUser::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.

2

Answers


  1. I think you missed setting the supports_credentials option to true in config/cors.php

    Login or Signup to reply.
  2. I can feel your pain, I struggled with it at my time.
    I’m using the same practice for my web app. I achieved it with the same steps.

    I notice one difference in env. I use:

    SESSION_DOMAIN=.get-set-sold.test
    SANCTUM_STATEFUL_DOMAINS=.get-set-sold.test
    

    ☝️ Use "." and remove https://

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search