manchenkoff / nuxt-auth-sanctum

Nuxt module for Laravel Sanctum authentication
https://manchenkoff.gitbook.io/nuxt-auth-sanctum/
MIT License
116 stars 16 forks source link

[Bug] useSanctumClient send an additional request to the /sanctum/csrf-cookie route on each request #88

Closed Delaylaph closed 1 month ago

Delaylaph commented 1 month ago

Hi, thanks for this library. I noticed that the client from useSanctumClient sends an extra request to the /sanctum/csrf-cookie route on each request. But wouldn't it be more correct to check if the XSRF-TOKEN is in the cookies, and insert it into the header if it is? It seems to me that we should make one request to get a token and then send that token in the header in all subsequent requests, rather than getting a new token for each request. Am I wrong?

Steps to reproduce the behavior: For example, if I send this request many times, the /sanctum/csrf-cookie request will also always be sent.

<script setup>
const client = useSanctumClient();

const requestFields = ref({});
const { data, error, execute, status } = await useAsyncData('register', () => client('/api/register', {
            method: 'POST',
            body: requestFields.value,
        }), {    
            lazy: true,
            immediate: false,
            watch: false
    });

const onSubmit = handleSubmit(async (values) => {
    requestFields.value = {
        email: values.email,
        password: values.password,
        password_confirmation: values.confirmPassword
    };
    await execute();
}); 
</script>

Response in the dev tools(don't mind the error status): image

Nuxt environment:

Module information

manchenkoff commented 1 month ago

Hey @Delaylaph, indeed you are right. Laravel documentation says that we have to request it once before the request and pass it for all subsequent ones. The reason I did it this way was to make sure that we have consistent value after logout on all sides CSR/SSR/API. But that's a good point that we can optimize it. I will try to take a look at possible solutions this week and open a PR with your suggestion.

Delaylaph commented 1 month ago

Sorry for the offtop, I have one more question. If I use ofetch interceptors, namely onRequest, it turns out that I override the behavior of onRequest by default and the logic that receives the XSRF-TOKEN does not work, do I understand correctly? It turns out that I can't use onRequest in my code. It's not critical for me, but I'm wondering if there's a way around it?

Example:

<script setup>
const { data, error, execute, status } = await useAsyncData('register', () => client('/api/register', {
            method: 'POST',
            body: requestFields.value,
            onRequest(ctx) { // breaks the logic => response: CSRF token mismatch.
                console.log(ctx);
            }
        }));
<script>
manchenkoff commented 1 month ago

It turns out that I can't use onRequest in my code. It's not critical for me, but I'm wondering if there's a way around it?

That's correct. Unfortunately, there is no way in ofetch library to register multiple interceptors separately. The only solution that came to my mind back then is to export request/response interceptors from the module to use with decorator pattern, but it was not that flexible and not very stable since it can interfere the logic and module no longer controls the behavior.

manchenkoff commented 1 month ago

Hey @Delaylaph, you can test v0.3.4 with this optimization implemented

Delaylaph commented 1 month ago

Now it seems to work fine. Thanks