Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Delaylaph opened this issue May 6, 2024 · 5 comments · Fixed by #91
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@Delaylaph
Copy link

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:

  • Version: 3.10.3
  • Mode: CSR
  • Environment: local

Module information

  • Version: 0.2.3
    Complete configuration:
sanctum: {
    baseUrl: process.env.API_URL,
    userStateKey: 'sanctum.user.identity',
    redirectIfAuthenticated: false,
    endpoints: {
        csrf: '/sanctum/csrf-cookie',
        login: '/login',
        logout: '/logout',
        user: '/api/user',
    },
    csrf: {
        cookie: 'XSRF-TOKEN',
        header: 'X-XSRF-TOKEN',
    },
    client: {
        retry: false,
    },
    redirect: {
        keepRequestedRoute: false,
        onLogin: '/',
        onLogout: '/',
        onAuthOnly: '/login',
        onGuestOnly: '/',
    },
    globalMiddleware: {
        enabled: false,
        allow404WithoutAuth: true,
    },
    logLevel: 3
  }
@Delaylaph Delaylaph added the bug Something isn't working label May 6, 2024
@manchenkoff
Copy link
Owner

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.

@manchenkoff manchenkoff added the enhancement New feature or request label May 6, 2024
@Delaylaph
Copy link
Author

Delaylaph commented May 6, 2024

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
Copy link
Owner

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
Copy link
Owner

manchenkoff commented May 12, 2024

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

@Delaylaph
Copy link
Author

Now it seems to work fine. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants