auth0 / nextjs-auth0

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

Issue Accessing Dynamically Loaded Environment Variables in Middleware #1769

Open muradsofi opened 2 weeks ago

muradsofi commented 2 weeks ago

Checklist

Description

We are storing environment variables in an external service (like Azure App Configuration) and have created an Auth0 instance manually due to this setup:

import { initAuth0 } from '@auth0/nextjs-auth0/edge';
import getConfig from 'next/config';

const { serverRuntimeConfig } = getConfig();

export const AUTH0_INSTANCE = initAuth0({
  secret: serverRuntimeConfig.AUTH0_SECRET,
  issuerBaseURL: serverRuntimeConfig.AUTH0_ISSUER_BASE_URL,
  baseURL: serverRuntimeConfig.AUTH0_BASE_URL,
  clientID: serverRuntimeConfig.AUTH0_CLIENT_ID,
  clientSecret: serverRuntimeConfig.AUTH0_CLIENT_SECRET,
});

However, because serverRuntimeConfig is not available in middleware, we attempted to update process.env in next.config.js file and use it for dynamically loading and updating environment variables like this:

const configureNext = async () => {
  const settings = await loadAzureAppConfig();
  Object.assign(process.env, settings); // Updating process.env

  const AUTH0_AUDIENCE = process.env.AUTH0_AUDIENCE;
  const AUTH0_BASE_URL = process.env.AUTH0_BASE_URL;
  const AUTH0_CLIENT_ID = process.env.AUTH0_CLIENT_ID;
  const AUTH0_CLIENT_SECRET = process.env.AUTH0_CLIENT_SECRET;
  const AUTH0_ISSUER_BASE_URL = process.env.AUTH0_ISSUER_BASE_URL;
  const AUTH0_SCOPE = process.env.AUTH0_SCOPE;
  const AUTH0_SECRET = process.env.AUTH0_SECRET;

  const nextConfig = {
    serverRuntimeConfig: {
      AUTH0_AUDIENCE,
      AUTH0_BASE_URL,
      AUTH0_CLIENT_ID,
      AUTH0_CLIENT_SECRET,
      AUTH0_ISSUER_BASE_URL,
      AUTH0_SCOPE,
      AUTH0_SECRET,
    },
  };

  return nextConfig;
};

Problem:

When trying to access these dynamically loaded process.env variables in middleware, they return as undefined. This results in errors like TypeError: "issuerBaseURL" must be a valid URI from the withMiddlewareAuthRequired function.

Question:

What is the correct approach to handle dynamically loaded environment variables in this context with @auth0/nextjs-auth0?

Reproduction

  1. Create a New Next.js Project:

  2. Set Up External Configuration Loader:

    • Create a configuration loader to fetch environment variables dynamically from an external service (like Azure App Configuration). For this example, use a mock function to simulate loading environment variables:
      // next-env-config/loadAzureAppConfig.js
      module.exports = async function loadAzureAppConfig() {
      return {
      AUTH0_AUDIENCE: 'https://example.auth0.com/api/v2/',
      AUTH0_BASE_URL: 'http://localhost:3000',
      AUTH0_CLIENT_ID: 'your-client-id',
      AUTH0_CLIENT_SECRET: 'your-client-secret',
      AUTH0_ISSUER_BASE_URL: 'https://example.auth0.com/',
      AUTH0_SCOPE: 'openid profile email',
      AUTH0_SECRET: 'your-auth0-secret',
      };
      };
  3. Modify next.config.js:

    • Update next.config.js to load environment variables asynchronously using the loader:
      
      // next.config.js
      const { loadAzureAppConfig } = require('./next-env-config/loadAzureAppConfig');

    const configureNext = async () => { const settings = await loadAzureAppConfig(); Object.assign(process.env, settings);

    return { serverRuntimeConfig: { AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE, AUTH0_BASE_URL: process.env.AUTH0_BASE_URL, AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET, AUTH0_ISSUER_BASE_URL: process.env.AUTH0_ISSUER_BASE_URL, AUTH0_SCOPE: process.env.AUTH0_SCOPE, AUTH0_SECRET: process.env.AUTH0_SECRET, }, }; };

    module.exports = configureNext();

  4. Set Up Auth0 Instance Manually:

    • Manually initialize the Auth0 instance using the dynamically loaded configuration:
      
      // lib/auth0.js
      import { initAuth0 } from '@auth0/nextjs-auth0/edge';
      import getConfig from 'next/config';

    const { serverRuntimeConfig } = getConfig();

    export const AUTH0_INSTANCE = initAuth0({ secret: serverRuntimeConfig.AUTH0_SECRET, issuerBaseURL: serverRuntimeConfig.AUTH0_ISSUER_BASE_URL, baseURL: serverRuntimeConfig.AUTH0_BASE_URL, clientID: serverRuntimeConfig.AUTH0_CLIENT_ID, clientSecret: serverRuntimeConfig.AUTH0_CLIENT_SECRET, });

  5. Create Middleware:

    • Set up middleware to protect routes and use the manually initialized Auth0 instance:
      
      // middleware.js
      import { NextRequest, NextResponse } from 'next/server';
      import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0';

    export async function middleware(request) { const secret = process.env.AUTH0_SECRET; // Trying to access dynamically loaded env variable

    if (!secret) { return NextResponse.redirect('/error'); // Redirect if secret is undefined }

    return withMiddlewareAuthRequired(request); }

    export const config = { matcher: ['/protected-route'], };

  6. Run the Project:

    • Start the Next.js development server with npm run dev.
    • Attempt to access the protected route (e.g., /protected-route).

Expected Result: Middleware should be able to access the dynamically loaded environment variables and perform authentication checks without errors.

Actual Result: The environment variables loaded asynchronously are undefined in the middleware, causing errors like TypeError: "issuerBaseURL" must be a valid uri.

Repository: You can create a minimal reproducible example by sharing this setup in a public GitHub repository.

Consistency: This issue can be reproduced consistently by following the steps above.

Additional context

No response

nextjs-auth0 version

3.1.0

Next.js version

13.5.5

Node.js version

v18.17.0

caineblood commented 2 weeks ago

that is malware to steal your account; do not under any circumstances download or run it. The post needs to be removed. If you have attempted to run it please have your system cleaned and your account secured immediately.

muradsofi commented 2 weeks ago

that is malware to steal your account; do not under any circumstances download or run it. The post needs to be removed. If you have attempted to run it please have your system cleaned and your account secured immediately.

For sure I will not download it :D I didn't know nowadays people try to steal account from github issues page lol

Hope repo owners will remove that comment when there are check my issue