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

[Feature] Support custom headers for `useSanctumClient` instance #95

Closed npldevfr closed 4 weeks ago

npldevfr commented 1 month ago

Hi, I would like to know if it is possible to inherit the client from useSanctumClient to add a permanent header like X-Localization

const { $i18n, $sanctumClient } = useNuxtApp()

export const client = $sanctumClient?.create({
  headers: {
    'X-Localization': $i18n.locale.value,
  },
})

However, $sanctumClient is sometimes undefined, which causes the requests to fail. Is there a cleaner way to handle this situation and ensure that the client is always properly initialized? Thank you!

manchenkoff commented 1 month ago

Hey @npldevfr 👋 useSanctumClient already returns an instance of fetch.create and I'm not sure that it is possible to globally assign headers like in your example. Right now, there is no common way of redefining headers in the module.

I'll be back from vacation in a week and I can check what other options we can do about it.

Maybe I will be able to implement a custom set of headers as a module config or user function that returns header collection or something like this.

carlosvaldesweb commented 1 month ago

I also want that, i need to add multi language but i cannot because i need to add manually to all calls.

"Accept-Language": useNuxtApp().$i18n.localeProperties.value.code
manchenkoff commented 1 month ago

After a quick look, I think I found a possible way of extending functionality by defining custom interceptors in app.config.ts which will be used in the module, it will be something like this

export default defineAppConfig({
    sanctum: {
        interceptors: {
            onRequest: async (nuxtApp: NuxtApp, context: FetchContext) => {
                // Here you can add your own headers or add custom callbacks for each request like telemetry and etc
                console.log('onRequest interceptor');
            },
            onResponse: async (nuxtApp: NuxtApp, context: FetchContext, response: FetchResponse<T>) => {
                // Here you can add your own headers or add custom callbacks for each response like telemetry and etc
                console.log('onResponse interceptor');
            },
        },
    },
});

I will try to implement it this week and open a PR, stay tuned 😄

Delaylaph commented 1 month ago

I made the composable around useSanctumClient and it works well. Here's an example of how I use it.

Composable:

export function useApiClient() {
  const  { locale }  = useNuxtApp().$i18n;
  const client = useSanctumClient();

  return client.create({
    headers: {
      locale: locale.value
    }
  });
}

export function useApiCall(key, url, body, handlerOptions, useAsyncDataOptions, globalError = false) {
    const client = useApiClient();
    const response = useAsyncData(key, () => client(url, { body: body?.value, ...handlerOptions}), useAsyncDataOptions);

    if(globalError) {
      watch(response.error, () => {
        if(response.error) {
          throw createError(response.error.value);
        }
      })
    }
    return response;
}

Usage:

<script setup>
const { error, execute, status } = await useApiCall('login', '/login', requestFields, {
        method: 'POST',
    }, {    
        lazy: true,
        immediate: false,
        watch: false
});
</script>
manchenkoff commented 4 weeks ago

The feature has been merged and will be published soon as well as documentation. I'll write here once it is ready.

manchenkoff commented 3 weeks ago

New version 0.3.7 has been published, check this documentation section - Interceptors

npldevfr commented 3 weeks ago

New version 0.3.7 has been published, check this documentation section - Interceptors

Great! Thanks for your reactivity 😄