DEV Community

Arjun Kumar
Arjun Kumar

Posted on

How to solve Authentication Issues When Deploying Node.js and Svelte to Production on Heroku?

As developers, we often encounter unexpected challenges when moving our applications from local development to production environments. Recently, I faced a perplexing issue with authentication in a Node.js and Svelte application using Passport.js. Here's the journey of troubleshooting and the surprising solution that finally resolved the problem.

The Setup

Our application stack:

  • Backend: Node.js with Express
  • Frontend: Svelte
  • Authentication: Passport.js

Everything worked flawlessly in the local development environment. The authentication flow was smooth, and we were ready to deploy to production. Little did we know the hurdles that awaited us.

The Production Puzzle

Upon deploying to production (in this case, Heroku), our authentication suddenly stopped working. The application that ran perfectly on localhost was now failing in the real world. It was time to put on our detective hats and dive into troubleshooting mode.

The Troubleshooting Journey

1. CORS Issues

The first suspect was CORS (Cross-Origin Resource Sharing). We double-checked our CORS configuration on the backend:

app.use(cors({ origin: 'https://your-frontend-url.com', credentials: true }));
Enter fullscreen mode Exit fullscreen mode

2. Fetch API Credentials

We ensured that our frontend Fetch API calls included the credentials: 'include' option:

fetch('https://your-api-url.com/login', {
  method: 'POST',
  credentials: 'include',
  // other options...
})
Enter fullscreen mode Exit fullscreen mode

3. Vite Config Proxy

We even tried setting up a proxy in our Svelte app's vite.config.js:

export default defineConfig({
  // other config...
  server: {
    proxy: {
      '/api': {
        target: 'https://your-api-url.com',
        changeOrigin: true,
        secure: false,
      }
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

4. Cookie Settings

We experimented with various cookie settings:

app.use(session({
  // other options...
  cookie: {
    secure: true, // We tried both true and false
    sameSite: 'none', // We tried different options here
  }
}));
Enter fullscreen mode Exit fullscreen mode

The Unexpected Solution

After hours of frustration and countless blog posts, the solution emerged from an unexpected place. The issue wasn't with CORS, fetch credentials, or cookie settings. The culprit was a single line of code that we hadn't considered:

app.set('trust proxy', 1);
Enter fullscreen mode Exit fullscreen mode

This line is crucial when your application is behind a reverse proxy, which is the case with Heroku. Without it, Express doesn't know it's behind a proxy and can't properly set secure cookies or determine the correct protocol (http vs https).

Why This Worked

Heroku uses a reverse proxy to handle incoming requests before they reach your application. This means that from your app's perspective, all requests appear to come from the proxy rather than the original client.

By setting trust proxy, we're telling Express to trust the X-Forwarded-* headers set by the proxy. This allows Express to:

  1. Correctly determine if the connection is secure (https).
  2. Set the secure flag on cookies when appropriate.
  3. Use the correct IP address for request logging and other purposes.

Lessons Learned

  1. Understand Your Hosting Environment: Different hosting platforms may have unique configurations that affect your application.

  2. Read Documentation Thoroughly: The solution was mentioned in Express.js documentation, but it's easy to overlook when you're not specifically looking for it.

  3. Don't Assume: Just because something works locally doesn't mean it will work in production without adjustments.

  4. Keep Learning: The web development landscape is vast, and there's always more to learn about the intricacies of deployment and production environments.

Conclusion

While troubleshooting can be frustrating, it's also an opportunity to deepen our understanding of the systems we work with. This experience highlighted the importance of considering the entire stack, including the hosting environment, when deploying web applications.

Remember, if you're deploying to a platform that uses a reverse proxy (like Heroku), don't forget to set trust proxy in your Express application. It might just save you hours of debugging!

Top comments (0)