I spend hours trying to debug googling arround but with no good result. I am using Laravel 8 with Sanctum package and latest Nuxt as frond-end. I setup couple endpoints and made them work - GET requests only. When I got to the forms section, where I need to retrieve information about form and then to be able to send this form data back to Laravel via POST request, I am not able within my set of middleware.
If I am using Api route, I end up at admin login page because of the
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
and if I use Web route, I end up at same login page because of the
'\App\Http\Middleware\EncryptCookies::class,'
if in both cases I comment them, my POST request goes through. To be exact, both work with Postman and I get no redirect. I get this behaviour only from Nuxt fetch.
This is example of my Nuxt code:
async function sendForm(){
if(form.value.email_honeypot == ''){
form.value.email_honeypot = props.data.honey;
await useFetch('/sanctum/csrf-cookie', { credentials: 'include' });
const token = useCookie('XSRF-TOKEN')
form.value._token = token.value;
formData.value.errors = {};
const { data: responseData, error, status } = await useCustomFetch('/api/forms-plugin/1/submit', { method: "POST", watch: false, body: form.value, headers: { Accept: 'application/json', 'X-XSRF-TOKEN': token.value }})
formData.value.response = responseData;
if(responseData.value.errors) {
for (const key in responseData.value.errors) {
const parts = key.split('.');
const fieldId = parseInt(parts[1]);
formData.value.errors[fieldId] = responseData.value.errors[key][0];
}
}
if(responseData.value.message) {
formData.value.success = true;
}
form.value.email_honeypot = '';
}
}
Fetching XSRF-TOKEN from sanctum works okay, I get those cookies to my Application cookie right. Could anyone help me with this?
Usually when post requests failed as I mentioned, my terminal gives me only this:
Closed without sending a request; it was probably just an unused speculative preconnection
cors.php
'paths' => ['*'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
.env
APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000
SESSION_DOMAIN=.localhost
SESSION_SECURE_COOKIE=false
SANCTUM_STATEFUL_DOMAINS=127.0.0.1:8000,localhost:3000,localhost
nuxt.config.ts
routeRules: {
'/api/**': {
proxy: { to: "http://localhost:8000/api/**" },
},
'/sanctum/**': {
proxy: { to: "http://localhost:8000/sanctum/**" },
}
}
useCustomFetch.ts
import type { UseFetchOptions } from 'nuxt/app'
import { defu } from 'defu'
export function useCustomFetch<T> (url: string, options: UseFetchOptions<T> = {}) {
const config = useRuntimeConfig()
const defaults: UseFetchOptions<T> = {
baseURL: config.public.baseUrl,
// cache request - causes trouble with url
// key: url,
// set user token if connected
headers: {
Authorization: `Bearer ${config.public.accessToken}`,
Accept: 'application/json',
},
credentials: 'include',
onResponse (_ctx) {
// _ctx.response._data = new myBusinessResponse(_ctx.response._data)
},
onResponseError (_ctx) {
// throw new myBusinessError()
}
}
// for nice deep defaults, please use unjs/defu
const params = defu(options, defaults)
return useFetch(url, params)
}
I tried commenting those two middlewares and it starts to work. So I guess I need to make it work with Sanctum EnsureFrontendRequestsAreStateful::class. But I do not know how.