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] Different baseUrl for server side rendering #115

Closed wethti closed 3 days ago

wethti commented 5 days ago

I have a docker setup with Nuxt 3 and Laravel in different containers. Nuxt 3 container therefore accesses the Laravel api by different urls on server side and on client side (the application url, same one the user is seeing in the browser for client-side requests and 'http://nginx', sending requests directly to the other docker containers on the server-side. However the plugin is using its own httpClient for making api requests, so I had to add that option.

Here is my solution:

in httpFactory.ts

const httpOptions: FetchOptions = {
        baseURL: options.baseUrl, // <- replace this line
        credentials: determineCredentialsMode(),

// with this:
baseURL: import.meta.server ? (options.SSRBaseUrl || options.baseUrl) : options.baseUrl,

That way, you can configure that alternative url in the nuxt.config.ts

export interface SanctumModuleOptions {
    /**
     * The base URL of the Laravel API.
     */
    baseUrl: string;
    /**
     * The base URL of the Laravel API to be used only for server side rendering (uses baseUrl for both client and server side by default)
     */
    SSRBaseUrl: string;
...
}

Here's an example with my config:

  sanctum: {

    baseUrl: import.meta.env.NODE_ENV === 'production' ? import.meta.env.SANCTUM_BASE_URL : import.meta.env.SANCTUM_DEV_BASE_URL,
    SSRBaseUrl: import.meta.env.SSR_BASE_URL,
    origin: import.meta.env.SANCTUM_ORIGIN_URL, // Nuxt app, by default will be used 'useRequestURL().origin'
    endpoints: {
      login: '/api/login',
      logout: '/api/logout',
      csrf: '/sanctum/csrf-cookie',
      user: '/api/user',
    },
    redirect: {
      keepRequestedRoute: true,
      onLogin: '/admin',
      onLogout: '/about',
      onAuthOnly: '/login',
      onGuestOnly: '/',  // these are for sending admins to admin panel on login
      onAdminAuth: '/admin', // these are for sending admins to admin panel on login
    }
  },

.env:

SANCTUM_BASE_URL=https://example.nuxtsanctum.ua
SANCTUM_DEV_BASE_URL=http://localhost:8876
SSR_BASE_URL=http://nginx
SANCTUM_ORIGIN_URL=http://localhost:3000

btw 'import.meta.' is the new 'process.' apparently

manchenkoff commented 3 days ago

Hey @wethti, thanks for the suggestion!

However, the feature seems to be a very platform-specific solution since there is no need to have 2 different endpoints in the production application. Usually, these DNS-related issues are solved out of the application scope.

For production applications, it should be always the same domain like api.domain.com or even TLD like domain.com if Token is used instead of CSRF.

For local development with Docker, you can easily set up the DNS host record to have a domain instead of localhost, for instance - laravel.test, and then the same domain will be used as a Docker container name, so it will be accessible from both SSR/CSR environments as http://laravel.test.

Example of docker container name - docker-compose.yml How to set up host records (automatically) - dns-proxy-server How to set up host records (manually) - Edit /etc/hosts on all OS

You can also check #57 for more details if HTTPS is required.