nuxt-community / auth-module

Zero-boilerplate authentication support for Nuxt 2
https://auth.nuxtjs.org
MIT License
1.93k stars 925 forks source link

Docs: Debugging SSR #1197

Open bmulholland opened 3 years ago

bmulholland commented 3 years ago

This is a collection of SSR debugging steps that I will passively collect - note that few of these are under the control of the auth module.

  1. Make sure you build, not generate, the assets.
  2. Configure the proxy, if you use one.
  3. Ensure your frontend server can access your backend server. Specifically, check that DNS is working and that the configured URL is accessible (e.g. via ipv6, if needed).
  4. Confirm that your url's are correctly configured for the browser and for the server
  5. Configure the full base URL
  6. Look for incompatibilities with your axios configuration
  7. Check that your configured user's payload property name is correct NOTE: for v5, use user.property instead.
  8. Ensure cookies are enabled, otherwise the server won't know who you are.
  9. Verify the referer is working as you expect.

For more ideas, check https://github.com/nuxt-community/auth-module/issues/258

thijsw commented 2 years ago

I have another debug step you could add to this list; I have lost a few hours because of it.

For local development, it is common to have a configuration like this:

axios: {
    baseURL: 'http://localhost:8000'
}

When using SSR nuxt.js is trying to reach the server via the ipv6 loopback interface ::1 but the host isn't necessarily reachable via ipv6. It is not immediately clear why the connection fails, hence the hours debugging. It is however easily solved by changing the base URL explicitly to the ipv4 variant http://127.0.0.1

bmulholland commented 2 years ago

Thanks, added :)

steven-fox commented 2 years ago

TL;DR: If your authentication needs the referer header present on a request and it isn't included in your SSR requests (even after configuring this auth package to do so), it may be because of a connection downgrade (HTTPS->HTTP) that strips the referer header on certain systems/browsers.


It appears a number of people are using this auth package in combination with Laravel Sanctum. Because of this, I'll mention the following, as it took me several ours to debug on top of the listed debugging steps. It is related to debug tip #9.

When using Laravel Sanctum (or another authentication protocol that relies on the referer header of a request) in combination with a request chain that will downgrade the connection protocol (HTTPS->HTTP), you may need to additionally include the origin header on your SSR request. A connection downgrade could come from various things, but a common one is having the api behind a load balancer performing SSL termination (and your SSR request will go through this load balancer - ie, your api and frontend are on different servers/networks).

To configure this:

// nuxt.config.js

export default {
  // ...

  auth: {
    // ...
    strategies: {
      laravelSanctum: {
        // ...
        provider: 'laravel/sanctum',
        url: process.env.SANCTUM_URL,
        endpoints: {
          login: { url: '/auth/login', method: 'post' },
          logout: { url: '/auth/logout', method: 'post' },
          user: {
            url: '/auth/user',
            method: 'get',
            withCredentials: true,
            headers: {
              referer: process.env.SANCTUM_REFERER,
              origin: process.env.SANCTUM_REFERER, // <-- ensure this domain matches one of your SANCTUM_STATEFUL_DOMAINS from your Laravel .env.
            },
          },
        },
      },
    },
    // ...
  },
}

Why does this happen? Many systems are configured to remove the referer header from a request when the connection protocol is downgraded. When the load balancer performs SSL termination (thus taking an HTTPS connection and passing it on as HTTP to your api servers), the chain may remove the referer header. This is what happened to us with our app deployed on Digital Ocean using their load balancer service. This caught us off guard, as our staging environment doesn't use a load balancer/SSL termination, so we had no issues with our testing. As soon as it hit production, the SSR requests needing authentication broke.

To remedy this with Sanctum, you can include the origin header, which will also be checked to determine if the request is coming from a stateful domain. You can review the Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::fromFrontend() method for more info.