sidebase / nuxt-auth

Authentication built for Nuxt 3! Easily add authentication via OAuth providers, credentials or Email Magic URLs!
https://auth.sidebase.io
MIT License
1.33k stars 164 forks source link

`defaultProvider` does not work with Custom OAuth #928

Open tschni opened 1 month ago

tschni commented 1 month ago

Environment

Reproduction

https://github.com/tschni/sidebase-nuxt-auth-default-provider-issue

Describe the bug

I have set up a custom OAuth provider with Authjs. In nuxt.config.ts I have set this as defaultProvider and activated the globalAppMiddleware.

Now I would have expected that when I opened the Nuxt app, I would automatically be redirected to the login page of my OAuth provider. This also fits with the following statement from the documentation: “Setting this here will also affect the global middleware behavior. For instance, when you set it to github and the user is unauthorized, they will be directly forwarded to the Github OAuth page instead of seeing the app-login page”.

However, there is a redirect to /api/auth/signin, where I first have to click a sign in button. Since I have only defined this one provider, I would of course like to skip this step and be redirected directly to the login page of my provider.

image image

There seems to have been the same error before, but without a helpful solution: https://github.com/sidebase/nuxt-auth/issues/531

Additional context

No response

Logs

No response

phoenix-ru commented 1 month ago

Could you please check that your CSRF token is verified?

https://github.com/nextauthjs/next-auth/blob/c15d9a5b7a435f4301572745add89cc99db30aef/packages/next-auth/src/core/index.ts#L241-L253

Sadly, I can't provide much other help as I don't have enough context and haven't set up custom providers with next-auth. Their current guide is lacking a section about CSRF protection https://next-auth.js.org/configuration/providers/oauth#using-a-custom-provider

tschni commented 1 month ago

How do I check the CSRF token? I'm not really familiar with next-auth unfortunately. However, I did not set anything out of the ordinary and strictly followed the instructions in the documentation.

Ibrahimmushtaq98 commented 1 month ago

Hi I also have been dealing with this issue. I have a Duende Identity provider and usually to replicate this, you add the globalAppMiddleware to true and to access a protected site with clear cookies/site data. I tried to investigate this since I am using a middleware of my own that basically just calls the signIn method if its not authenticated.

In the useAuth.js file i found the area of code that affects the URL generation for the redirect

  const fetchSignIn = () => _fetch(nuxt, `/${action}/${provider}`, {
    method: "post",
    params: authorizationParams,
    headers,
    body
  }).catch((error2) => error2.data);
  const data = await callWithNuxt(nuxt, fetchSignIn);

Returns a url with the csrf being true cause the header did not contain next-auth.csrf-token

data: {
  "url": "https://localhost:3000/api/auth/signin?csrf=true"
}

Further investigation for this since i littered signIn function in useAuth.js code with console log for my example

Provider: identityserver
callbackUrl: /dashboard
signinUrl: https://localhost:3000/api/auth/signin
queryParams: ?callbackUrl=%2Fdashboard
hrefSignInAllProviderPage: https://localhost:3000/api/auth/signin?callbackUrl=%2Fdashboard
csrfToken: 435256e1b8897123bdc6609743dae1f598cdd57df43bb77ff5f835fc688b12de
headers: {
  "Content-Type": "application/x-www-form-urlencoded",
  "cookie": "__Secure-next-auth.callback-url=https%3A%2F%2Flocalhost%3A3000%2Fdashboard
}
actions: signin
body: {}
params: undefined
data: {
  "url": "https://localhost:3000/api/auth/signin?csrf=true"
}
href: https://localhost:3000/api/auth/signin?csrf=true

As opposed to having a csrf token in place

Provider: identityserver
callbackUrl: dashboard
signinUrl: https://localhost:3000/api/auth/signin
queryParams: ?callbackUrl=%2Fdashboard
hrefSignInAllProviderPage: https://localhost:3000/api/auth/signin?callbackUrl=%2Fdashboard
csrfToken: 8efbcdaaf6fc58d2ecf57aedaf130d3dd52be1e298840180ba7521f66cd3b888
headers: {
  "Content-Type": "application/x-www-form-urlencoded",
  "cookie": "__Secure-next-auth.callback-url=https%3A%2F%2Flocalhost%3A3000%2Fdashboard; next-auth.csrf-token=8efbcdaaf6fc58d2ecf57aedaf130d3dd52be1e298840180ba7521f66cd3b888%7C7fc5a894fec0d6cc8b13d4168220707aeeffd4ef6ef7a4893580d7e31b7d71a3"
}
actions: signin
body: {}
params: undefined
data: {
  "url": "REDACTED HERE, BUT A PROPER URL TO THE PROVIDER"
}
href: "REDACTED HERE, BUT A PROPER URL TO THE PROVIDER"

I wonder if this helps, at this time, I think im just going to put the globalAppMiddleware to false and put per page signIn which is annoying

Edit: 2024-10-23

I would like to add my middleware that I am using, it may help to debug whatever is going here with CSRF stuff

export default defineNuxtRouteMiddleware((to, from) => {
  const config = useRuntimeConfig()
  const { status, signIn } = useAuth();
  const basePath = config.public.FRONTEND_PRIMARY_BASE_URL;

  const isAuthenticated = status.value === "authenticated";

  // Return immediately if user is already authenticated
  if (isAuthenticated) {
    if (to.matched.length === 0 && (basePath as string) != undefined && (basePath as string) != null) {
      let url = new URL(to.path, (basePath as string)).href;

      return navigateTo(url, { redirectCode: 301, external: true });
    }
    return
  }

  return signIn('identityserver', { callbackUrl: to.path, redirect: true }) as ReturnType<typeof navigateTo>
});