next-auth icon indicating copy to clipboard operation
next-auth copied to clipboard

callbackUrl seems to be ignored

Open bduff9 opened this issue 3 years ago • 8 comments

Describe the bug

Using callbackUrl with email, google, and twitter providers. I would expect the application to redirect to this URL after successful sign-in. Instead, it always redirects to the root.

Steps to reproduce

const { error: signInError } = await signIn('email', {
  callbackUrl,
  email,
  redirect: false,
});

..where callbackUrl is currently hardcoded to http://localhost:3000/picks/set. I have confirmed this value, however, there is a cookie I see with the name next-auth.callback-url that is always set to http%3A%2F%2Flocalhost%3A3000.

Expected behavior

I would expect the application to be redirected to http://localhost:3000/picks/set after successful authentication.

Screenshots or error logs

N/A

Additional context

I am using the latest NextAuth (3.13.0) and NextJS (10.0.9). Node version is 14.15.4.

Feedback Documentation refers to searching through online documentation, code comments and issue history. The example project refers to next-auth-example.

  • [X] Found the documentation helpful
  • [ ] Found documentation but was incomplete
  • [ ] Could not find relevant documentation
  • [ ] Found the example project helpful
  • [ ] Did not find the example project helpful

bduff9 avatar Mar 18 '21 01:03 bduff9

There's a solution while this bug isn't fixed. $ yarn add cookies

Then on your page:

import Cookies from 'cookies'

add this to getServerSideProps(context):

const cookies = new Cookies(context.req, context.res)
cookies.set("next-auth.callback-url", <URL>)

thanks for pointing out to next-auth.callback-url

rmgpinto avatar Apr 02 '21 08:04 rmgpinto

@bduff9 could you please link to a reproduction?

balazsorban44 avatar Apr 02 '21 15:04 balazsorban44

I have the same issue.

@rmgpinto Thanks for the workaround. I managed to get it working using your suggestion locally. But when I deploy the application it does not work.

I can see that the "next-auth.callback-url" is correctly set, but it seems to ignore it.

Running locally (by building / running and with dev server): http://localhost:3000/login_route -> (LOGIN) -> http://localhost:3000/wanted_route

Deployed: https://<my_website>.com/login_route -> (Login) -> https://<my_website>.com ???

Any suggestions?

EDIT: I'm using docker to build/deploy and the suggested Dockerfile provided by Next.js docs. EDIT2: I noticed that the __Secure-next-auth.callback-url is https://<my_website>.com but the next-auth.callback-url is https://<my_website>.com/wanted_route EDIT3: I tried running the docker image locally and it "fails". Might need some extra config for docker? EDIT4: Managed to make it work locally with docker using options for cookies. Still fails when I deploy it though.

I tried setting domain with combinations of : httpOnly: false, secure:false, httpOnly: true, secure: true

Also tried:

  cookies.set('next-auth.callback-url', <URL>, {
    path: '/',
    httpOnly: false,
  }

Now both __Secure-next-auth.callback-url and next-auth.callback-url are set to https://<my_website>.com/wanted_route

Still redirects to https://<my_website>.com

khenrix avatar Apr 12 '21 15:04 khenrix

Here're some of the efforts I've tried to get callbacks to work but also subdomains too.

Specifically if you want to pass callbackUrl inside your redirect_url for Twitter and other OAuth 1.x providers, here's what fixed it:

provider.callbackUrl = provider.callbackUrl + `?callbackUrl=` + encodeURIComponent(req.options.callbackUrl)

Check previous commits in that branch to get a better picture.

I know maintainers are focusing on the 4.x branch and options are not exposed there in the same way, but could be useful if you guys decide to revive the subdomains + callbackUrls persisted.

eugenehp avatar Sep 26 '21 19:09 eugenehp

I'm running in the same issue while trying to use Next Auth as a centralized/common auth infrastructure for cli login.

I've created a minimal repro example: https://github.com/geovanisouza92/next-auth-standalone-auth

geovanisouza92 avatar Jan 23 '22 16:01 geovanisouza92

I just stumbled upon this issue today. We have an application that serves multiple domains, meaning that the callbackUrl is dynamic on each request. This issue makes that impossible, and I have not found any work around yet.

renevangsgaardjp avatar Jun 02 '22 14:06 renevangsgaardjp

I managed to get one step further, by overwriting redirect_uri on each sign in, like this:

signIn("keycloak", undefined, {
  redirect_uri: `https://${host}/api/auth/callback/keycloak`,
})

Now the redirect_uri is set correctly when redirecting to the auth provider (keycloak).

The issue now is that when I get back, next-auth attempts to fetch id token, and it fails by sending the wrong redirect_uri to the auth provider. This is the log statements from next-auth:

[next-auth][error][OAUTH_CALLBACK_ERROR] 
https://next-auth.js.org/errors#oauth_callback_error invalid_grant (Incorrect redirect_uri) {
  error: {
    message: 'invalid_grant (Incorrect redirect_uri)',
    stack: 'OPError: invalid_grant (Incorrect redirect_uri)\n' +
      ... clipped ...
    name: 'OPError'
  },
  providerId: 'keycloak',
  message: 'invalid_grant (Incorrect redirect_uri)'
}

As I am uncertain if my issue is completely related to this issue, I have created another issue https://github.com/nextauthjs/next-auth/issues/4668.

renevangsgaardjp avatar Jun 07 '22 14:06 renevangsgaardjp

I have found a workaround fix (tested locally and production) for this issue by doing the following:

in [...nextauth.ts] add a custom login page:

pages: {
  signIn: '/login',
},

in [...nextauth.ts] add the following under callbacks:

callbacks: {
  async redirect({ url, baseUrl }) {
    // Allows relative callback URLs
    if (url.startsWith("/")) return `${baseUrl}${url}`
    // Allows callback URLs on the same origin
    else if (new URL(url).origin === baseUrl) return url
    return baseUrl
  },
}

in custom login page (e.g login.tsx) :

import { signIn } from 'next-auth/react'
import { useRouter } from 'next/router'
const router = useRouter()

signIn('credentials', {
  redirect: false,
  callbackUrl: `${
    router.query.callbackUrl
      ? router.query.callbackUrl
      : window.location.origin
  }`,
})

in any page (e.g: index.tsx) :


export async function getServerSideProps(context) {
  const { req, resolvedUrl } = context
  const session = await getSession({ req })
  const destination = `${process.env.NEXTAUTH_URL}${resolvedUrl}`
  const callbackUrl = `/login?callbackUrl=${encodeURIComponent(destination)}`
  
  if (!session) {
    return {
      redirect: {
        destination: callbackUrl,
        permenant: false,
      },
    }
  }

  if (session) {
    return {
      props: {
        session,
      },
    }
}

ShadiBlitz avatar Jun 27 '22 19:06 ShadiBlitz

I had a similiar issue and fixed it by specifiying the NEXTAUTH_URL with the proper base domain like https://example.org. This properly reformatted the callback url to my expected host.

DracoBlue avatar Nov 02 '22 10:11 DracoBlue

@ShadiBlitz This worked very well. Thanks so much for sharing.

I'm assuming that when we implement a custom sign in page, we opt-out of the default auto callBackUrl functionality? If this is true, I'd love to see this added as an info blurb in the documentation.

elliotgonzalez-lk avatar Dec 13 '22 14:12 elliotgonzalez-lk

I had a similiar issue and fixed it by specifiying the NEXTAUTH_URL with the proper base domain like https://example.org. This properly reformatted the callback url to my expected host.

This helped me understand why when I was using a custom basePath my project didn't get the right callbackUrl while using debug:true

I thought my NEXTAUTH_URL had to be

NEXTAUTH_URL=https://localhost:3000/custom-path

When it had to be

NEXTAUTH_URL=https://localhost:3000/custom-path/api/auth

Then the callbackUrl started to reflect the proper value 😉 And the rest is history

To see your callbackUrl - which for my provider creates the redirect_url use debug the following in your [...nextauth].js

export default NextAuth({
  debug: true,
  providers: [
  ....
})

etiennejcharles avatar Jan 10 '23 23:01 etiennejcharles

I for the life of me can't figure out how to use Next Auth with ngrok. My URLs keep changing on every app build, and the redirect Url is always incorrect.

Has anyone got Next Auth and ngrok working?

noah-haub avatar Jan 12 '23 16:01 noah-haub

same issues .

Google provider can redirect collectly, but Apple provider not. i don't know why same logic cause two different result.

geminiyellow avatar Feb 13 '23 11:02 geminiyellow

Please check if setting the env NEXTAUTH_URL in https://github.com/nextauthjs/next-auth/issues/1542#issuecomment-1300016433 helps.

I was only searching for callbackUrl because my next url was not correct. Fixing it, fixed my issue. Leaving no other changes - especially to the callbackUrl - necessary at all.

DracoBlue avatar Feb 13 '23 19:02 DracoBlue

thank you for your help. but i don't think my setting is wrong. when use debug true, only problem is when use apple provider get the wrong cookies callback Url. i don't know where it was come from.

maybe i can update it before goto sns auth page.

Please check if setting the env NEXTAUTH_URL in https://github.com/nextauthjs/next-auth/issues/1542#issuecomment-1300016433 helps.

I was only searching for callbackUrl because my next url was not correct. Fixing it, fixed my issue. Leaving no other changes - especially to the callbackUrl - necessary at all.

geminiyellow avatar Feb 14 '23 14:02 geminiyellow

finally, i change the cookies's sameSite to none it work.

geminiyellow avatar Feb 28 '23 02:02 geminiyellow

I cannot reproduce this issue in v4, so I'll close it. Feel free to reopen a new issue if you still have the problem 🙇‍♂️

ThangHuuVu avatar Mar 25 '23 07:03 ThangHuuVu



signIn('credentials', {

The magic for me was putting the right callback url in the signIn method:

<button 
  onClick={()=> signIn('google', {
    callbackUrl: `${new URLSearchParams(window.location.search).get('callbackUrl')}`
  })}
>
  Sign in with Google
</button>

gregg-cbs avatar Apr 14 '23 21:04 gregg-cbs

I'm using a custom Oauth provider setup, and have the same issue. There are lots of moving parts (custom auth) in my solution, so very hard to prepare a replication example. The solution from comment helped.

I feel like the server-side getServerSideProps interactions with the session, should be documented in more detail.

mifrej avatar May 09 '23 09:05 mifrej

I added to the .env.local file in the root, NEXTAUTH_URL=<your_domain>api/auth and the problem was solved

MGlobus avatar Jul 30 '23 09:07 MGlobus