auth0 / nextjs-auth0

Next.js SDK for signing in with Auth0
MIT License
2.01k stars 381 forks source link

next build failing with missing environment variables #1356

Closed nickzelei closed 9 months ago

nickzelei commented 1 year ago

Checklist

Description

I'm running next build against a fresh repo generated with the create next app and am running into build errors due to missing Auth0 environment variables.

It seems that this is because I don't have a .env.local with the environment variables specified there. Why do I need this? These will be provided at runtime, so am confused as to why they are failing build steps.

I followed these two issues which seem to have fixed this, but I am not seeing that.

npm run build             

> my-app@0.1.0 build
> next build

- info Creating an optimized production build  
- info Compiled successfully
- info Linting and checking validity of types  
- info Collecting page data ..TypeError: "secret" is required
    at get (/Users/nick/code/playground/my-app/.next/server/chunks/877.js:367:15)
    at getConfig (/Users/nick/code/playground/my-app/.next/server/chunks/877.js:1664:45)
    at getInstance (/Users/nick/code/playground/my-app/.next/server/chunks/877.js:2744:63)
    at handleAuth (/Users/nick/code/playground/my-app/.next/server/chunks/877.js:2791:31)
    at 83739 (/Users/nick/code/playground/my-app/.next/server/app/api/auth/[auth0]/route.js:126:32)
    at __webpack_require__ (/Users/nick/code/playground/my-app/.next/server/webpack-runtime.js:25:42)
    at __webpack_exec__ (/Users/nick/code/playground/my-app/.next/server/app/api/auth/[auth0]/route.js:172:39)
    at /Users/nick/code/playground/my-app/.next/server/app/api/auth/[auth0]/route.js:173:78
    at __webpack_require__.X (/Users/nick/code/playground/my-app/.next/server/webpack-runtime.js:138:21)
    at /Users/nick/code/playground/my-app/.next/server/app/api/auth/[auth0]/route.js:173:47

> Build error occurred
Error: Failed to collect page data for /api/auth/[auth0]
    at /Users/nick/code/playground/my-app/node_modules/next/dist/build/utils.js:1156:15
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  type: 'Error'
}
- info Collecting page data .%     

Reproduction

  1. npx create-next-app@latest
  2. Add /app/api/auth/[auth0]/route.ts file with the recommended setup.
  3. npm run build

You can skip the first two steps by cloning my repo here: https://github.com/nickzelei/auth0-bug Running npm run build results in an error due to missing environment variables.

This can be fixed by adding a basic .env.local file

AUTH0_SECRET=replace-with-your-own-secret-generated-with-openssl
AUTH0_BASE_URL=http://localhost:3000
AUTH0_ISSUER_BASE_URL='https://example.com'
AUTH0_CLIENT_ID='{CLIENT_ID}'
AUTH0_CLIENT_SECRET='{CLIENT_SECRET}'
AUTH0_AUDIENCE=
AUTH0_SCOPE='openid profile'

Additional context

No response

nextjs-auth0 version

3.1.0

Next.js version

13.4.13

Node.js version

18.16.0

adamjmcgrath commented 1 year ago

Hi @nickzelei - thanks for raising this

Originally I thought this was an issue with Next.js trying to statically render an API route when it used a Dynamic function.

But I see the SDK is trying to get config before Next.js can bail out of static rendering the route. I don't think this is going to get fixed on the Next.js end, so I'll leave this open to investigate a solution.

In the meantime, you can use your workaround of providing dummy values to the build.

pkabra commented 1 year ago

+1 running into this. My builders are spread across different environments so ideally I'd like to avoid remembering to update the environments everywhere. Working around this right now by just having some default environment variables everywhere. Specifically impacting APIs using the App Router and withApiAuthRequired.

nextjs-auth0 version - 3.0.1 Next.js version - 13.4.12 Node.js version - 18.7.1

nguaman commented 1 year ago

Perhaps this bug is related to the following pull request (https://github.com/vercel/next.js/pull/54203), which was fixed in version v13.4.19.

g12i commented 1 year ago

I fixed this by calling handleAuth inside the route handler as such:

export const GET = async (req, ctx) => {
  const response = await handleAuth()(req, ctx);
  return response;
};

You can avoid calling it each time by lazy storing it in scope:

import { handleAuth, type AppRouteHandlerFn } from "@auth0/nextjs-auth0";

let _handleAuth: AppRouteHandlerFn | undefined;

export const GET: AppRouteHandlerFn = async (req, ctx) => {
  if (typeof _handleAuth === "undefined") {
    _handleAuth = handleAuth() as AppRouteHandlerFn;
  }
  const response = await _handleAuth(req, ctx);
  return response;
};
nickzelei commented 1 year ago

It makes sense that lazy loading it will fix it as the environment variables won't be access until they need to be (which is how it should be imo 😄 ) - however, I'm not sure putting the handleAuth inside of a GET function is the way to go here. handleAuth is intended to be used as a spread and offers more than just GET methods. Most of the auth methods are POST I believe. While it might compile, I have doubts that it would work as intended.

g12i commented 1 year ago

These two are mutual:

export const GET = x();
export const GET = (...args) => x()(...args);

Except, of course, that the x() is called in runtime. At the end of the day handleAuth returns the same NextJS route handler (see here). So it's all GET requests. The spread is used to catch multiple routes (/login,/logout, /callback, etc.) but not the HTTP method.

tr3ysmith commented 11 months ago

Yeah I'm running into this when pushing to Azure Static Web Apps as well... This seems ridiculous to check for a secret during CI...

Implementing the fix from @g12i worked, Thanks!!

kangbojk commented 11 months ago

still encounter the error

My app/api/auth/[auth0]/route.js

import {
  handleAuth,
  handleLogin,
  handleLogout,
  handleProfile
} from "@auth0/nextjs-auth0";

let _handleAuth;

export const GET = async (req, ctx) => {
  if (!_handleAuth) {
    _handleAuth = handleAuth;
  }

  const response = await _handleAuth({
    login: handleLogin({
      authorizationParams: {
        audience: process.env.AUTH0_AUDIENCE,
        // If you want to check the authorization server for if you have a
        // session, you need to visit it with a login (you can use `prompt=none``
        // to fail silently if the user doesn't have a session).
        prompt: "login",
        scope: "email offline_access openid profile readwrite:any"
      },
      returnTo: "/incidents"
    }),
    logout: handleLogout(() => {
      return {
        returnTo: "/"
      };
    }),
    profile: handleProfile({ refetch: true }),
    onError(req, error) {
      console.error("An Auth0 error occured:", error);
    }
  })(req, ctx);
  return response;
};
tommyguo commented 10 months ago

@g12i's fix does fix the TypeError: "secret" is required error originating from api/auth/[auth0]/route.ts but I'm still seeing the error for pre-rendered pages:

Error occurred prerendering page "/dashboard". Read more: https://nextjs.org/docs/messages/prerender-error
TypeError: "secret" is required
adamjmcgrath commented 10 months ago

Hi all 👋 - I've published an experimental tag that defers reading the configuration of the SDK until request time, which allows the SDK to instruct Next.js to bail out of static rendering before the config is read - full pr is https://github.com/auth0/nextjs-auth0/pull/1541 (interesting bit is https://github.com/auth0/nextjs-auth0/commit/bec7d6c5998ba06ae87cb906235d7568bab2418f#diff-c3095d5010e65c52737a98a5d618ea24049ebe90c8470752426081d70ed6e012)

@nickzelei - I've tested it on your repo and confirm that the project builds successfully without the .env.local

I'd be grateful if a few other people who have requested this tried it out too and let me know if they experience any issues.

You can test the experimental tag by installing the SDK like so npm i @auth0/nextjs-auth0@experimental-lazy-conf

nickzelei commented 10 months ago

hey @adamjmcgrath your changes seem to allow a build now.

I reproduced by:

  1. git clone git@github.com:nickzelei/auth0-bug.git && cd auth0-bug
  2. npm install
  3. npm run build <-- fail
  4. npm i @auth0/nextjs-auth0@experimental-lazy-conf
  5. npm run build <-- success

Awesome!

cyber-nic commented 9 months ago

@adamjmcgrath, thank you for resolving the previous issue.

Retracting my comment as this thread is unrelated to my concern.