nuxt-modules / supabase

Supabase module for Nuxt.
https://supabase.nuxtjs.org
MIT License
666 stars 123 forks source link

Auth session missing! (500) causes prerendering to fail #388

Open oripka opened 1 month ago

oripka commented 1 month ago

I just updated to 1.3.1 and my app does not npx nuxi build anymore because of 500 errors in the prerendering.

Version

@nuxtjs/supabase: v1.3.1 nuxt: 3.12.3

Steps to reproduce

I have a middleware server/middleware/auth.ts (shortened) and use the composables in various pages, components and composables. Before version v.1.3.0 and switching new library in https://github.com/nuxt-modules/supabase/pull/357 this did not happen.

import { serverSupabaseClient } from '#supabase/server'
import { serverSupabaseUser } from '#supabase/server'
export default defineEventHandler(async (event) => {
    let user = await serverSupabaseUser(event);
    const url = event.node.req.url

    if (url?.includes('/api/_content')) {
        /...*/
        const client = await serverSupabaseClient(event)
        /...*/
    }
})

Error in v.1.3.1

[...]
ℹ ../.nuxt/dist/server/_nuxt/_id_-2JCAlXmO.js                                       251.10 kB │ map:   141.20 kB                                      2:30:31 PM
ℹ ../.nuxt/dist/server/_nuxt/entry-styles-1.mjs-Ch3EK2p4.js                         506.21 kB │ map:     0.11 kB                                      2:30:31 PM
ℹ ../.nuxt/dist/server/server.mjs                                                 1,292.94 kB │ map: 2,184.18 kB                                      2:30:31 PM
ℹ ✓ built in 33.98s                                                                                                                                   2:30:31 PM
✔ Server built in 33992ms                                                                                                                             2:30:31 PM
ℹ Initializing prerenderer                                                                                                                      nitro 2:30:31 PM
ℹ Prerendering 3 routes                                                                                                                         nitro 2:30:48 PM

 ERROR  (node:61564) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.                       2:30:48 PM
(Use node --trace-deprecation ... to show where the warning was created)

  ├─ /api/_content/cache.1720700937569.json (13ms)                                                                                               nitro 2:30:48 PM
  │ └── Error: [500] Auth session missing!
  ├─ /__studio.json (3ms)                                                                                                                        nitro 2:30:48 PM
  │ └── Error: [500] Auth session missing!
  ├─ /aboutus/ (7ms)                                                                                                                             nitro 2:30:48 PM
  │ └── Error: [500] Auth session missing!
                                                                                                                                                 nitro 2:31:08 PM
Errors prerendering:
  ├─ /api/_content/cache.1720700937569.json (13ms)                                                                                               nitro 2:31:08 PM
  │ └── Error: [500] Auth session missing!
  ├─ /__studio.json (3ms)                                                                                                                        nitro 2:31:08 PM
  │ └── Error: [500] Auth session missing!
  ├─ /aboutus/ (7ms)                                                                                                                             nitro 2:31:08 PM
  │ └── Error: [500] Auth session missing!
                                                                                                                                                 nitro 2:31:08 PM

 ERROR  Exiting due to prerender errors.                                                                                                               2:31:08 PM

  at prerender (node_modules/.pnpm/nitropack@2.9.7_magicast@0.3.4/node_modules/nitropack/dist/chunks/prerender.mjs:220:11)
  at async node_modules/.pnpm/nuxt@3.12.3_@parcel+watcher@2.4.1_@types+node@20.14.10_eslint@8.57.0_ioredis@5.4.1_magicast@0_q7sdyrtoabysbtwp23uowyg5zq/node_modules/nuxt/dist/index.mjs:3605:7
  at async build (node_modules/.pnpm/nuxt@3.12.3_@parcel+watcher@2.4.1_@types+node@20.14.10_eslint@8.57.0_ioredis@5.4.1_magicast@0_q7sdyrtoabysbtwp23uowyg5zq/node_modules/nuxt/dist/index.mjs:5469:5)
  at async Object.run (node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/chunks/build.mjs:94:5)
  at async runCommand$1 (node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1648:16)
  at async runCommand$1 (node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1639:11)
  at async runMain$1 (node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1777:7)

 ERROR  Exiting due to prerender errors.                 
dalisys commented 1 month ago

I am having the same problem

Here is how you can reproduce it (just need to add (SUPABASE_URL and SUPABASE_KEY to .env):

https://github.com/mohamed-ali-masmoudi/supa-nuxt-500

radum2o18 commented 1 month ago

+1 ... I've updated the nuxt module to the latest version (1.3.5) from 1.2.2 and now getting this error as well. Running nuxt 3.12.4. Error occurs immediately after running pnpm dev.

at createError (./node_modules/.pnpm/h3@1.12.0/node_modules/h3/dist/index.mjs:78:15) at serverSupabaseUser (./node_modules/.pnpm/@nuxtjs+supabase@1.3.5/node_modules/@nuxtjs/supabase/dist/runtime/server/services/serverSupabaseUser.js:7:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at Object.handler (./server/middleware/user.ts:4:1) at async ./node_modules/.pnpm/h3@1.12.0/node_modules/h3/dist/index.mjs:1975:19 at async Object.callAsync (./node_modules/.pnpm/unctx@2.3.1/node_modules/unctx/dist/index.mjs:72:16) at async toNodeHandle (./node_modules/.pnpm/h3@1.12.0/node_modules/h3/dist/index.mjs:2266:7) at async ufetch (./node_modules/.pnpm/unenv@1.10.0/node_modules/unenv/runtime/fetch/index.mjs:9:17) at errorhandler (./nodemodules/.pnpm/nuxt@3.12.4@parcel+watcher@2.4.1_@types+node@20.14.11_eslint@9.7.0_ioredis@5.4.1_magicast@0._7nch5kmaryphufa7epwejavc3y/node_modules/nuxt/dist/core/runtime/nitro/error.js:37:41) at async Server.toNodeHandle (./node_modules/.pnpm/h3@1.12.0/node_modules/h3/dist/index.mjs:2274:9)

Fwosty commented 1 month ago

I believe this is a possible temporary workaround.

export default defineEventHandler(async (event) => {
  const client = await serverSupabaseClient(event);
  const { data } = await client.auth.getUser();

  if (data.user) {
    event.context.user = {
      id: data.user.id,
      email: data.user.email,
    };
  }
});
dalisys commented 1 month ago

@Fwosty Thanks for the workaround!

The problem is that Nuxt executes the files under "/server/middleware" on every request for all the routes also for "/" where in our case the user is not logged yet.

Here are two other potential workarounds:

1- Set a list for the protected routes (that should include the user)

import { serverSupabaseUser } from '#supabase/server';
const protectedRoutes = [
  "/api/admin",
  "/api/user"
]
export default defineEventHandler(async (event) => {
  const url = event.node.req.url
  if(protectedRoutes.some(route => url?.includes(route)) ) {
    console.log("Auth needed: ", event.node.req.url)
    try {
      const user = await serverSupabaseUser(event);
      if (user) {
        event.context.user = user;
      }
    } catch (error) {
      console.info(' #####  Auth error #####');
      console.error(error);
    }
  }
  else{
    console.log("No Auth needed: ", event.node.req.url)
  }
});

2- Just make it non blocking by catching the error

import { serverSupabaseUser, serverSupabaseClient } from "#supabase/server";

export default defineEventHandler(async (event) => {
  try {
  const user = await serverSupabaseUser(event);
  event.context.user = user;
  } catch (error) {
  console.error("Auth error: ", error);
  }
});
oripka commented 1 month ago

I tried the second approach at some obvious places in my app where the stack traces helped but then I still get these kind of generic stack traces.

Before a search for all instances of import { serverSupabaseUser } from '#supabase/server', is this kind of behavior now wanted or is this a bug? If it is wanted I think we should update the docs on how to handle this properly.


 ERROR  Auth error                                                                                                                                     7:45:48 AM

  ├─ / (318ms)                                                                                                                                   nitro 7:45:49 AM
  │ └── Error: [500] Auth session missing!
  ├─ /course/cysecxtra (321ms)                                                                                                                   nitro 7:45:49 AM
  │ └── Error: [500] Auth session missing!
  ├─ /api/_content/cache.1721886316781.json (4478ms)                                                                                             nitro 7:45:53 AM

 ERROR  Auth error (repeated 519 times)                                                                                                                7:45:48 AM

                                                                                                                                                 nitro 7:46:00 AM
Errors prerendering:
  ├─ / (318ms)                                                                                                                                   nitro 7:46:00 AM
  │ └── Error: [500] Auth session missing!
  ├─ /course/cysecxtra (321ms)                                                                                                                   nitro 7:46:00 AM
  │ └── Error: [500] Auth session missing!
                                                                                                                                                 nitro 7:46:00 AM

 ERROR  Exiting due to prerender errors.                                                                                                               7:46:00 AM

  at prerender (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nitropack@2.9.7_magicast@0.3.4/node_modules/nitropack/dist/chunks/prerender.mjs:220:11)
  at async /Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxt@3.12.4_@parcel+watcher@2.4.1_@types+node@20.14.11_eslint@9.7.0_ioredis@5.4.1_magicast@0._3c2rhs6qure5ukjumkuozoma4m/node_modules/nuxt/dist/index.mjs:3615:7
  at async build (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxt@3.12.4_@parcel+watcher@2.4.1_@types+node@20.14.11_eslint@9.7.0_ioredis@5.4.1_magicast@0._3c2rhs6qure5ukjumkuozoma4m/node_modules/nuxt/dist/index.mjs:5479:5)
  at async Object.run (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/chunks/build.mjs:94:5)
  at async runCommand$1 (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1648:16)
  at async runCommand$1 (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1639:11)
  at async runMain$1 (/Users/otr/code/labguides-refactor/node_modules/.pnpm/nuxi@3.12.0/node_modules/nuxi/dist/shared/nuxi.6aad497e.mjs:1777:7)

 ERROR  Exiting due to prerender errors.                                                                                                               7:46:00 AM
radum2o18 commented 2 weeks ago

anyone managed to get this working? the workarounds prevent the app from crashing but this leaves the server routes unprotected...been stuck with this for almost 2 weeks now...

oripka commented 2 weeks ago

I just pinned the 1.2.2 version.

dalisys commented 2 weeks ago

@radum2o18, I just implemented the first approach with a protected routes list.

For example, you can set all your protected routes like this (but you have to edit the folder structure):

const protectedRoutes = [
  "/api/protected",
]

With this setup, my protected routes always require a user, and for the public ones, I don't set the user and don't get any error

Ragura commented 1 week ago

Also getting this since upgrading. It would be nice not to have to build in a workaround when nothing's supposed to be changed to warrant this.

oripka commented 1 week ago

The workaround 1 works for me, but I have to do it on every middleware any anything that might get used while prerendering during build including server api routes. It basically makes sense to implement a helper that wraps serverSupabaseUser just for this.

th1m0 commented 5 days ago

serverSupabaseUser will throw an error if there is no session(user is not logged in). This means you will have to wrap this in a try/catch block to handle the unauthenticated state.

Example:

import { serverSupabaseUser } from "#supabase/server"

export default defineEventHandler(async (event) => {
  try {
    const user = await serverSupabaseUser(event);
    if (!user) {
      event.context.user = null;
      // Handle unauthenticated case
      return
    }

    event.context.user = user;
  } catch (error) {
    event.context.user = null;
    // Handle unauthenticated case
  }
})

Maybe serverSupabaseUser should just return a { data, error } object like most supabase methods do, but that would be a breaking change.