Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursion detected at /session #973

Open
IqroNegoro opened this issue Dec 29, 2024 · 28 comments
Open

Recursion detected at /session #973

IqroNegoro opened this issue Dec 29, 2024 · 28 comments
Labels
bug A bug that needs to be resolved pending An issue waiting for triage

Comments

@IqroNegoro
Copy link

Environment


  • Operating System: Windows_NT
  • Node Version: v22.12.0
  • Nuxt Version: 3.15.0
  • CLI Version: 3.17.2
  • Nitro Version: 2.10.4
  • Package Manager: [email protected]
  • Builder: -
  • User Config: default
  • Runtime Modules: @nuxtjs/[email protected], @sidebase/[email protected]
  • Build Modules: -

Reproduction

I think i don't need minimal reproduction because this problem is happening as soon as i try to including the modules for auth

Describe the bug

My problem is when i trying to use OAuth for login with google

bun add @sidebase/nuxt-auth next-auth

config :

auth: {
    isEnabled: true,
    baseURL: "http://localhost:3000/api/auth/",
    originEnvKey: "AUTH_ORIGIN",
    provider: {
      type: "authjs",
      defaultProvider: "google"
    },
  },

endpoint in ~/server/api/auth/[...].ts

import { NuxtAuthHandler } from "#auth";
import GoogleProvider from "next-auth/providers/google";

export default NuxtAuthHandler({
    secret: process.env.AUTH_SECRET,
    providers: [
        GoogleProvider.default({
            clientId: process.env.GOOGLE_CLIENT_ID!,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
        })
    ]
});

just it is, but when i load the website again ( i don't do anything)

ERROR  [@sidebase/nuxt-auth] Recursion detected at /session. Have you set the correct auth.baseURL?

i think it should work well because i have the file in auth folder in ~/server/api/auth/[...].ts < use wildcard for all routes matching

do i miss something?

Additional context

No response

Logs

ℹ nuxt-auth setup starting                                                                               
...
[sidebase-auth 17.43.28] ℹ Selected provider: authjs. Auth API location is http://localhost:3000/api/auth/, if you would like to change this, see https://auth.sidebase.io/guide/application-side/configuration#baseurl. Ensure that the NuxtAuthHandler({ ... }) is there, see https://auth.sidebase.io/guide/authjs/nuxt-auth-handler
✔ nuxt-auth setup done                                                                                   
...
ERROR  [@sidebase/nuxt-auth] Recursion detected at /session. Have you set the correct auth.baseURL?
ERROR  [@sidebase/nuxt-auth] Recursion detected at /session. Have you set the correct auth.baseURL?
ERROR  [@sidebase/nuxt-auth] Recursion detected at /session. Have you set the correct auth.baseURL?
@IqroNegoro IqroNegoro added bug A bug that needs to be resolved pending An issue waiting for triage labels Dec 29, 2024
@agracia-foticos
Copy link

Same issue

@Emehprincewill
Copy link

I got same Error

ERROR [@sidebase/nuxt-auth] Recursion detected at /session. Have you set the correct auth.baseURL?

But when I set the following config in dev mode on the nuxt,config.ts it was resolved:

auth: {
originEnvKey: 'http://localhost:3000',
baseURL: 'http://localhost:3000/api/auth',
}

@NathanD19
Copy link

Finding the same problem.
Following @Emehprincewill example gets it to work again. Not ideal.

Does not work:
originEnvKey: 'AUTH_ORIGIN',
baseURL: process.env.AUTH_BASE_URL,

@CognizanterGroup
Copy link

Yea not ideal for production. I till have same problem reading it from the runtimeconfig.

@ybybybybyb
Copy link

Just found the fix. You need to remove the slash in baseURL and if you wet the AUTH_ORIGIN, it now need to include the full path

AUTH_ORIGIN=http://localhost:3000/api/auth

@TonyBrownDev
Copy link

Same issue. Watching.

@Plinpod
Copy link

Plinpod commented Jan 8, 2025

From what I could tell if you have AUTH_ORIGIN set in your .env it overwrites your baseURL value in nuxt.config.ts

set AUTH_ORIGIN=http://localhost:3000/api/auth and remove baseURL in nuxt config.

@IqroNegoro
Copy link
Author

i have use another nuxt module brah, i think I'll close this issue

@TonyBrownDev
Copy link

TonyBrownDev commented Jan 9, 2025 via email

@NathanD19
Copy link

Which module did you go with @TonyBrownDev /@IqroNegoro ?

@IqroNegoro
Copy link
Author

Which module did you go with @TonyBrownDev /@IqroNegoro ?

i use Nuxt and i just need Google OAUTH2 Sign In, so i use this module, this module so straightforward for what i want :
https://nuxt.com/modules/nuxt-vue3-google-signin

@TonyBrownDev
Copy link

@NathanD19 - I ended up using https://authjs-nuxt.pages.dev/, and implemented the Google sign in provider. It seemed to work perfectly in my case. Best of luck!

@NathanD19
Copy link

NathanD19 commented Jan 9, 2025

Thanks for the info! I'll take a look at these.

@danangs57
Copy link

why this issue is closed, its still occuring

@Download
Copy link

Yeah even after multiple people chimed in to say it was also occurring for them.

@IqroNegoro can you reopen so we don't have to recreate this? Issue is real and not fixed.

@IqroNegoro
Copy link
Author

Yeah even after multiple people chimed in to say it was also occurring for them.

@IqroNegoro can you reopen so we don't have to recreate this? Issue is real and not fixed.

have you tried @Emehprincewill solution?

@IqroNegoro IqroNegoro reopened this Jan 28, 2025
@Download
Copy link

@IqroNegoro Thanks for re-opening! 👍

I did indeed try @Emehprincewill 's solution. It did fix it for me.
I have been able to tweak it a bit to at least get rid of the hardcoded URLs.

nuxt.config.ts:

  auth: {
    originEnvKey: 'AUTH_ISSUER',
    baseURL: `${process.env.AUTH_ORIGIN}/api/auth`,
    provider: {
      type: 'authjs',
      defaultProvider: 'keycloak',
    },
  },

Setting originEnvKey and baseURL like this solved it for me.

I have these environment variables set in my .env file, like this:

AUTH_ORIGIN = http://localhost:3000
NUXT_AUTH_ISSUER = http://localhost:8080/realms/my-realm

However, this seems to be just a workaround. I did not have to do this before. It would pick up the environment variables correctly without these extra two lines in nuxt.config.ts. So I'm guessing this is actually a bug somewhere. Could be a change in next-auth / authjs, I don't know. But I don't think we should close this issue until we find out. And if indeed this workaround is needed for the time being, we maybe should add it in the docs somewhere.

Note: I am setting AUTH_ISSUER in the runtime config section, like so:

  runtimeConfig: {
    AUTH_ISSUER: 'http://localhost:8080/realms/my-realm',
    // ...
  },

There is some mechanism that takes process.env.NUXT_AUTH_ISSUER and assigns it to the runtime config AUTH_ISSUER key. The name originEnvKey suggests it needs the name of the environment variable when in fact it seems it needs the name of the runtime config key.... But I am not well versed enough in Nuxt and its runtime config mechanism to know for sure. Anyway, hope this helps someone.

@IqroNegoro
Copy link
Author

@IqroNegoro Thanks for re-opening! 👍

I did indeed try @Emehprincewill 's solution. It did fix it for me. I have been able to tweak it a bit to at least get rid of the hardcoded URLs.

nuxt.config.ts:

auth: {
originEnvKey: 'AUTH_ISSUER',
baseURL: ${process.env.AUTH_ORIGIN}/api/auth,
provider: {
type: 'authjs',
defaultProvider: 'keycloak',
},
},
Setting originEnvKey and baseURL like this solved it for me.

I have these environment variables set in my .env file, like this:

AUTH_ORIGIN = http://localhost:3000
NUXT_AUTH_ISSUER = http://localhost:8080/realms/my-realm
However, this seems to be just a workaround. I did not have to do this before. It would pick up the environment variables correctly without these extra two lines in nuxt.config.ts. So I'm guessing this is actually a bug somewhere. Could be a change in next-auth / authjs, I don't know. But I don't think we should close this issue until we find out. And if indeed this workaround is needed for the time being, we maybe should add it in the docs somewhere.

Note: I am setting AUTH_ISSUER in the runtime config section, like so:

runtimeConfig: {
AUTH_ISSUER: 'http://localhost:8080/realms/my-realm',
// ...
},
There is some mechanism that takes process.env.NUXT_AUTH_ISSUER and assigns it to the runtime config AUTH_ISSUER key. The name originEnvKey suggests it needs the name of the environment variable when in fact it seems it needs the name of the runtime config key.... But I am not well versed enough in Nuxt and its runtime config mechanism to know for sure. Anyway, hope this helps someone.

Maybe there is issue with prefix NUXT, like in next.js where some variable need prefix NEXT for working... So instead AUTH_ISSUER, maybe that need prefix NUXT before it... Idk exactly.

And I have no idea why there is no one in this module team that showing up?

@Download
Copy link

Download commented Jan 28, 2025

After doing some more digging, I am suspecting that this issue might be related to the breakage:

#655

It specifically mentions some of the environment variables that we have to change to get things working again...

Closed in 0.10.0: https://auth.sidebase.io/guide/advanced/url-resolutions

If you follow the link, it talks about AUTH_ORIGIN and originEnvVars and baseURL...

Also, this commit has been changing the URL resolution just last month:
5788005

Not trying to fingerpoint. Just trying to get this issue rolling.

Also, just found this PR which definitely seems related:

#925

This line would explain why suddenly I need to specify originEnvKey even though I am setting it to the default value:

// Note: the `server` condition is here because Nuxt explicitly filters out all the env variables for the Client build,
// thus the check can be safely dropped. Instead of it, the `runtime/plugin` would set the `baseURL` on the runtime config.
if (import.meta.server !== false && authRuntimeConfig.originEnvKey) {
  // Override base URL using environment variable specified in `originEnvKey` if any.
  // By default, would use `AUTH_ORIGIN`, can be changed by user
  const envBaseURL = process.env[authRuntimeConfig.originEnvKey]
  if (envBaseURL) {
    baseURL = envBaseURL
  }
}

https://github.com/sidebase/nuxt-auth/blame/main/src/runtime/utils/url.ts#L42

Seems that if authRuntimeConfig.originEnvKey == '', this code block will be skipped... So should authRuntimeConfig.originEnvKey return the default value of AUTH_ORIGIN when not explicitly set? Why do we check if it is set in the first place? If not set it should default to AUTH_ORIGIN no?

originEnvKey

Type: string
Default: AUTH_ORIGIN
The name of the environment variable that holds the origin of the application. This is used to determine the origin of your application in production.

By default, NuxtAuth will look at AUTH_ORIGIN environment variable and runtimeConfig.authOrigin.

https://auth.sidebase.io/guide/application-side/configuration#originenvkey

@Download
Copy link

Download commented Jan 28, 2025

Just found the fix. You need to remove the slash in baseURL and if you wet the AUTH_ORIGIN, it now need to include the full path

AUTH_ORIGIN=http://localhost:3000/api/auth

I really hope this is wrong. Because origin has a very defined meaning and it explicitly does NOT include a path. It is a combination of protocol, host and port. E.g http://localhost:3000 is an origin, but http://localhost:3000/path is an URL on the same origin. The path simply is never part of the origin. Browsers use the term origin extensively. As in 'same-origin policy' etc.

Origin

Web content's origin is defined by the scheme (protocol), hostname (domain), and port of the URL used to access it. Two objects have the same origin only when the scheme, hostname, and port all match.

https://developer.mozilla.org/en-US/docs/Glossary/Origin

Asking for an origin and then expecting it to include a path is just wrong.... ¯\_(ツ)_/¯

@Download
Copy link

@zoey-kaiser Can you have a look at this issue? I suspect it is an unintended consequence of your commit 5788005 from last month.

@BracketJohn Adding you as you seem to be top committer for this project.

Basically the last release seems to have broken many people that now have to make workarounds in their config and we are all just guessing here. This issue needs some love from the regular maintainers.

@Download
Copy link

Download commented Jan 28, 2025

Workaround

Add originEnvKey: 'AUTH_ISSUER' to the auth key in nuxt.config.ts:

auth: {
  originEnvKey: 'AUTH_ISSUER',
  provider: {
    type: 'authjs',
    defaultProvider: 'keycloak',
  },
},

I just checked that, at least in my app, specifying baseURL was not needed after all. Just setting 'AUTH_ISSUER' fixes the issue for me.

EDIT: I was mixing up AUTH_ISSUER and AUTH_ORIGIN in some of my comments...

The default value for originEnvKey is AUTH_ORIGIN according to the docs. In my config so far, I have always set that to the origin of the Nuxt server. The origin of the authentication server (Keycloak in my case) I have always specified in AUTH_ISSUER (NUXT_AUTH_ISSUER)...

E.g in .env:

# Nuxt server
AUTH_ORIGIN = http://localhost:3000

# Keycloak server
NUXT_AUTH_ISSUER = http://localhost:8080/realms/my-realm

Apparently, this interpretation was wrong??

I am totally confused now but I hope the maintainers can make more sense of it.

In the Nuxt docs it says about originEnvKey that it is "The name of the environment variable that holds the origin of the application. This is used to determine the origin of your application in production.". So this is talking about my application, which has the Nuxt server running on http://localhost:8080... So why does this workaround, which is effectively pointing it at the Keycloak server, even working??

Workaround 2

Apparently, it is only important that originEnvKey is modified. This workaround also works for my app:

auth: {
  originEnvKey: '',
  provider: {
    type: 'authjs',
    defaultProvider: 'keycloak',
  },
},

I am currently debugging this by inserting console.log statements in the Nuxt code to see what is happening. Sorry for all the updates but I am hoping I can help you find the cause and fix it.

Workaround 3

After doing more debugging I noticed that in fact, setting originEnvKey was a red herring. It did not actually pick up the AUTH_ISSUER since in .env this variable is called NUXT_AUTH_ISSUER and it actually reads directly from process.env and not from runtimeConfig, so it ended up being undefined, which in development ends up using the runtime hostname from the request, while printing the AUTH_NO_ORIGIN error message.

Turns out that one of two possible changes has to be made:

  1. In the .env file, update AUTH_ORIGIN to include the path, OR
  2. In nuxt.config.ts set baseURL manually

Workaround 3.1:

.env

AUTH_ORIGIN = http://localhost:3000/api/auth

Workaround 3.2:

nuxt.config.ts

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  // ...
  auth: {
    // https://github.com/sidebase/nuxt-auth/issues/973
    baseURL: `${process.env.AUTH_ORIGIN}/api/auth`,
    provider: {
      type: 'authjs',
      defaultProvider: 'keycloak',
    },
  },
  // ...
});

I use the second method. This way, at least you don't have to change all the .env files that are already deployed and you can at least in the config act as if origin means what it is supposed to mean.

@phoenix-ru
Copy link
Collaborator

Hi @Download, thank you for a very involved investigation! I am the main author of #913 which changed quite a lot of logic regarding paths.
As you correctly noticed, I wrote an extensive guide at https://auth.sidebase.io/guide/advanced/url-resolutions regarding how the new logic works, as well as a migration guide here https://auth.sidebase.io/upgrade/version-0.10.0

Asking for an origin and then expecting it to include a path is just wrong.... ¯_(ツ)_/¯

I absolutely agree with you here and you are correct, the name origin is misleading. Both for you and for us as well, but this comes from inconsistencies within authjs (most recent PR which attempts to ease such inconsistencies).

We have long considered renaming the variable to something which makes more sense, and we did so in the past already. I explicitly opted into NOT changing the default name AUTH_ORIGIN to make the adoption of 0.10.0 a bit easier.
In my opinion, updating nuxt.config.ts is easier than meddling with environment variables. At least in our infrastructure, envs are managed by DevOps and not by the project team.

Version 0.10 is not finalized yet, there are several important pathing fixes still pending. I would suggest that you follow the official documentation and report if some claims there are false/misleading, this would greatly help for sure 🙂

There is some mechanism that takes process.env.NUXT_AUTH_ISSUER and assigns it to the runtime config AUTH_ISSUER key.

This is the default behaviour of Nuxt's Runtime Config. I had lots of struggle to get it working correctly because of all the "magic" it does. The current solution is likely final:

  • with SSR
    • inside plugin which runs before server rendering, baseURL will be resolved from an environment variable
      // Note: the `server` condition is here because Nuxt explicitly filters out all the env variables for the Client build,
      // thus the check can be safely dropped. Instead of it, the `runtime/plugin` would set the `baseURL` on the runtime config.
      if (import.meta.server !== false && authRuntimeConfig.originEnvKey) {
      // Override base URL using environment variable specified in `originEnvKey` if any.
      // By default, would use `AUTH_ORIGIN`, can be changed by user
      const envBaseURL = process.env[authRuntimeConfig.originEnvKey]
      if (envBaseURL) {
      baseURL = envBaseURL
      }
      }
      • if originEnvKey is set - server will read process.env[originEnvKey]
      • if originEnvKey is not set - default to reading process.env.AUTH_ORIGIN;
    • this value will then be sent to client via re-assignment to runtimeConfig.public.auth
      // Set the correct `baseURL` on the server,
      // because the client would not have access to environment variables
      if (import.meta.server) {
      runtimeConfig.baseURL = resolveApiBaseURL(wholeRuntimeConfig)
      }
  • without SSR
    • the module will use the static baseURL defined in nuxt.config.ts
      // Default to static runtime config (still overridable using `NUXT_PUBLIC_AUTH_BASE_URL`)
      let baseURL = authRuntimeConfig.baseURL
    • there is no access to environment variables and thus not possible to use them. You are expected to set baseURL
  • value will be read from runtimeConfig.public.auth.baseURL

Turns out that one of two possible changes has to be
In the .env file, update AUTH_ORIGIN to include the path, OR
In nuxt.config.ts set baseURL manually

These are actually two of the intended methods and not workarounds.

Prior to 0.10 there were lots of problems with AUTH_ORIGIN needing a / at the end. There is also some implicit URL handling logic inside next-auth which was hiding the problems and confusing everyone, including us, the maintainers of NuxtAuth. They call variable host and later origin which is the source of your confusion.


I think the improvements we should still land:

  • Clarify how the resolution works with SSR disabled (items from above are not in the docs);
  • Fix originEnvKey not respected when ssr: false #991 and allow picking up custom environment variables during build;
  • Schedule renaming of AUTH_ORIGIN to AUTH_BASE_URL and originEnvKey to baseURLEnvKey to be included into 0.11.
    • Possible route - deprecation and allowing both configs for 0.11, removing deprecated usage afterwards

@Download
Copy link

Thanks for your detailed response.

I have to add that after writing my last comment, I found out an extra source of confusion, which is that when we modify .env, the Nuxt dev server rebuilts but does NOT actually pick up the new values. Probably because the env module caches them. This leads to some false positives where I thought it was (still) working, but in fact it was not. So do a full restart if you change .env.

In the end I concluded that 'workaround' 3.2 of setting

  baseURL: `${process.env.AUTH_ORIGIN/api/auth`

did not actually work. It was only working because my previous change of the .env file was still in the cache. So it seems to me that only changing AUTH_ORIGIN in .env actually works.... Altough I would expect that that second workaround would also work it does not actually seem to?

Schedule renaming of AUTH_ORIGIN to AUTH_BASE_URL

Yeah I am not sure. One point of confusion here for me is that there often is an extra auth server. Like the Keycloak server in my case. So when you say AUTH_BASE_URL, are you talking about Keycloak? I now know you are not, but it is confusing.

Maybe AUTH_NUXT_ENDPOINT = http://localhost:3000/api/auth is more clear?

@phoenix-ru
Copy link
Collaborator

are you talking about Keycloak

The provider-specific configuration is generally inside the [...].ts file where you call NuxtAuthHandler. So far, there was no real confusion as to what is what. Inside the handler you can of course use any environment variables you want

@Download
Copy link

Yeah ok.

Schedule renaming of AUTH_ORIGIN to AUTH_BASE_URL and originEnvKey to baseURLEnvKey to be included into 0.11

I missed that you also propose changing originEnvKey. That is a good idea and then it all makes perfect sense 👍

I do have one more suggestion / idea.... Currently, my .env file looks like this:

.env

NUXT_AUTH_ENDPOINT = http://localhost:3000/api/auth
NUXT_AUTH_SECRET = ....
NUXT_AUTH_ISSUER = http://localhost:8080/realms/my-realm
NUXT_CLIENT_ID = myapp
# NUXT_CLIENT_SECRET = ...
NUXT_SESSION_STRATEGY = 'jwt'
NUXT_SESSION_MAX_AGE = 2592000  # seconds (30 days)
NUXT_SESSION_UPDATE_AGE = 86400 # seconds (24 hours)
NUXT_IDP_LOGOUT = true
NUXT_AUTH_DEBUG = true

and I am setting originEnvKey as follows:

nuxt.config.ts

auth: {
  originEnvKey: 'NUXT_AUTH_ENDPOINT`,
  // ...
}

...so I am effectively renaming AUTH_ORIGIN already...

But you can maybe see the pattern... I prefixed all env vars with NUXT_, because that is their convention for runtimeConfig. I am declaring that runtime config as follows:

nuxt.config.ts

runtimeConfig: {
  AUTH_DEBUG: '',
  AUTH_ENDPOINT: '',
  AUTH_ISSUER: '',
  AUTH_SECRET: '',
  SESSION_STRATEGY: 'jwt',
  SESSION_MAX_AGE: `${30 * 24 * 60 * 60}`, // 30 days
  SESSION_UPDATE_AGE: `${24 * 60 * 60}`, // 24 hours
  CLIENT_ID: 'myapp',
  CLIENT_SECRET: '',
  IDP_LOGOUT: 'true',
},

As you can see, the advantage of choosing a name starting with NUXT_ is that I can make that environment variable available in runtimeConfig. I could not do this with AUTH_ORIGIN since Nuxt expects it to start with NUXT_.... So if you rename this variable, I would set the default to NUXT_AUTH_BASE_URL i.s.o. AUTH_BASE_URL. This makes it fit into the general naming scheme and also makes more clear that this is the base url for the Nuxt side of things and not the base url of the auth server itself...

So:

  • Rename AUTH_ORIGIN to NUXT_AUTH_BASE_URL
  • Rename originEnvKey to baseUrlEnvKey
  • Set default value for baseUrlEnvKey to 'NUXT_AUTH_BASE_URL'

Would maybe be best?

@phoenix-ru
Copy link
Collaborator

Rename AUTH_ORIGIN to NUXT_AUTH_BASE_URL

Unfortunately this idea already came to me and I tested it with no success. There was actually such a change after #848, which got reverted iirc.

In a perfect world, you would simply set the default values on runtimeConfig itself, for instance:

runtimeConfig: {
  public: {
    auth: {
      baseURL: 'http://localhost:3000/api/auth'
    }
  }
}

And you'd expect that setting NUXT_PUBLIC_AUTH_BASE_URL in runtime overrides this default value. However, Nuxt behaves very inconsistently, thus we prefer not to rely on it for now.

But your suggestion of course makes a lot of sense!

@Download
Copy link

IIRC, the reason this was not working was that the code that was checking process.env for AUTH_ORIGIN was in Auth JS itself, so it knew nothing about NUXT...

and the reason for using AUTH_ORIGIN was for (backward?) compatibility with Auth JS...

But I'm not sure so...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug that needs to be resolved pending An issue waiting for triage
Projects
None yet
Development

No branches or pull requests