I’m creating a Laravel / React SPA Application using Sanctum Stateful Auth. I’n my local enviroment it works just fine. Cookies are being sent and everything is ok, but when I pass the app to production ( I’m using a shared hosting ). The stateful auth breaks and doesn’t work. It allows me to login, but when I try to go to a guarded query, it throws: Unauthenticated.
Debugging I can see that my apollo client is not sending the cookie credentials, while in my local environment, it does.
Ligthouse config:
'route' => [
/*
* The URI the endpoint responds to, e.g. mydomain.com/graphql.
*/
'uri' => '/graphql',
/*
* Lighthouse creates a named route for convenient URL generation and redirects.
*/
'name' => 'graphql',
/*
* Beware that middleware defined here runs before the GraphQL execution phase,
* make sure to return spec-compliant responses in case an error is thrown.
*/
'middleware' => [
// Ensures the request is not vulnerable to cross-site request forgery.
// NuwaveLighthouseHttpMiddlewareEnsureXHR::class,
// Always set the `Accept: application/json` header.
NuwaveLighthouseHttpMiddlewareAcceptJson::class,
// Logs every incoming GraphQL query.
// NuwaveLighthouseHttpMiddlewareLogGraphQLQueries::class,
LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class,
],
],
cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie','graphql','graphiql'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'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,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
Frontend Apollo Client:
import {ApolloClient, InMemoryCache, ApolloProvider, gql} from '@apollo/client';
import {createHttpLink} from "@apollo/client";
const link = createHttpLink({
uri: import.meta.env.VITE_GRAPHQL_ENDPOINT,
credentials: 'same-origin',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
});
const client = new ApolloClient({
cache: new InMemoryCache(),
link
});
export default client;
I also want to point out that, if I use graphiql, and call the login mutation, the rest of the queries and mutations that are guarded work just fine ( Within graphiql ) It’s just the frontend side that doesn’t work.
VITE_GRAPHQL_ENDPOINT="https://university-react.xyz/graphql"
SESSION_DOMAIN=university-react.xyz