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

signIn() error/cancel ends up in api/auth/signin?error=Callback#_=_ #7753

Closed
khteh opened this issue Jun 7, 2023 · 13 comments
Closed

signIn() error/cancel ends up in api/auth/signin?error=Callback#_=_ #7753

khteh opened this issue Jun 7, 2023 · 13 comments
Labels
triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@khteh
Copy link

khteh commented Jun 7, 2023

Environment

System:
OS: Linux 6.2 Ubuntu 23.04 23.04 (Lunar Lobster)
CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12800H
Memory: 46.05 GB / 62.45 GB
Container: Yes
Shell: 5.2.15 - /bin/bash
Binaries:
Node: 19.8.1 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 9.5.1 - /usr/local/bin/npm
Browsers:
Chrome: 114.0.5735.106
Firefox: 113.0.2

Reproduction URL

https://github.com/nextauthjs/next-auth-example

Describe the issue

How to properly handle errors on signin()? For example, cancelling the signIn operation from the provider should redirect back to the login or home page instead of ending up at api/auth/signin?error=Callback#_=_

How to reproduce

Launch https://github.com/nextauthjs/next-auth-example and then cancel the signin or provide invalid credentials. How to properly handle signin error so that it could redirect to proper page?

Expected behavior

Being able to properly redirect the user to the home page when user cancels the sign in.

@khteh khteh added the triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. label Jun 7, 2023
@avukalov
Copy link

avukalov commented Jun 10, 2023

Same thing happens when using Duende IdentityServer. Actually we can override signin page using pages configuration..
Check Pages

@khteh
Copy link
Author

khteh commented Jun 11, 2023

No, it never reach any of the page configured at all!

@avukalov
Copy link

avukalov commented Jun 11, 2023

Try using this guide #3154

I just tested it, and it works for me.

I use the following versions:

"next": "13.4.4"
"next-auth": "^4.22.1"
and the app router.

app/api/auth/[...nextauth]/route.ts

const authOptions: AuthOptions = {
  providers, // Duende Identity Server settings
  callbacks,
  // events
  pages: {
    signIn: "/auth/signin",
  }
}

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }

app/auth/signin/page.tsx

"use client"

import { useRouter, useSearchParams } from "next/navigation"
import React, { useEffect } from 'react'

const Signin = () => {
  const router = useRouter();
  const searchParams = useSearchParams();

  useEffect(() => {
    const error = searchParams.get('error');

    // TODO: Handle case if manually navigated 

    if (error === "Callback") {
      router.push("/")
    } 
  }, []);

  return (
    <div> </div>
  )
}

export default Signin

When calling signIn('duende-identityserver6'), I was redirected directly to the Duende Login page. After canceling the login, I was redirected back to my custom signin component (app/auth/signin), where I can handle the error.

If you want to reach your custom login page before redirecting to the identity provider, you should call signIn() without specifying a provider.

Hope it helps! 😃

However, I am unsure if this error can be handled at this time.

[next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
https://next-auth.js.org/errors#oauth_callback_handler_error access_denied {
  error: {
    message: 'access_denied',
    stack: 'Error: access_denied\n' +
      '    at oAuthCallback (webpack-internal:///(sc_server)/./node_modules/next-auth/core/lib/oauth/callback.js:56:23)\n' +
      '    at Object.callback (webpack-internal:///(sc_server)/./node_modules/next-auth/core/routes/callback.js:18:111)\n' +
      '    at AuthHandler (webpack-internal:///(sc_server)/./node_modules/next-auth/core/index.js:202:51)\n' +
      '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
      '    at async NextAuthRouteHandler (webpack-internal:///(sc_server)/./node_modules/next-auth/next/index.js:49:30)\n' +
      '    at async NextAuth._args$ (webpack-internal:///(sc_server)/./node_modules/next-auth/next/index.js:83:24)\n' +
      '    at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:242:37)',
    name: 'Error'
  },
  error_description: undefined,
  providerId: 'duende-identityserver6',
  message: 'access_denied'
}
[next-auth][error][OAUTH_CALLBACK_ERROR]
https://next-auth.js.org/errors#oauth_callback_error access_denied {
  message: 'access_denied',
  stack: 'Error: access_denied\n' +
    '    at oAuthCallback (webpack-internal:///(sc_server)/./node_modules/next-auth/core/lib/oauth/callback.js:56:23)\n' +
    '    at Object.callback (webpack-internal:///(sc_server)/./node_modules/next-auth/core/routes/callback.js:18:111)\n' +
    '    at AuthHandler (webpack-internal:///(sc_server)/./node_modules/next-auth/core/index.js:202:51)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async NextAuthRouteHandler (webpack-internal:///(sc_server)/./node_modules/next-auth/next/index.js:49:30)\n' +
    '    at async NextAuth._args$ (webpack-internal:///(sc_server)/./node_modules/next-auth/next/index.js:83:24)\n' +
    '    at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:242:37)',
  name: 'Error'
}

@khteh khteh closed this as completed Jun 12, 2023
@khteh khteh reopened this Jun 12, 2023
@khteh
Copy link
Author

khteh commented Jun 12, 2023

Reopen this because the other application doesn't work with this solution. It ends up in /auth/signin?callbackUrl=https%3A%2F%2Fwww.mydomain.io%2F&error=Callback#_=_. I use the same configuration as the other working application which works perfectly.

callbacks redirect which does NOT work:

      async redirect ({ url, baseUrl }) {
        const origin = new URL(url).origin
        console.log(`redirect url: ${url}, baseUrl: ${baseUrl}, URL(url).origin: ${origin}`)
        return url
      },

callbacks redirect which does works:

        async redirect ({ url, baseUrl }) {
          const origin = new URL(url).origin
          console.log(`adminportal redirect url: ${url}, baseUrl: ${baseUrl}, URL(url).origin: ${origin}`)
          return `${baseUrl}/management/overviews`
        },

This lets me think that the case which works is because ${baseUrl}/management/overviews actually redirects to the home page, which is a login page, if the user is not authenticated. The case which does NOT work doesn't do so.

Any idea what could be the root cause here? Thanks.

@avukalov
Copy link

I don't have an idea, but maybe this somehow helps...

According to the documentation:

The redirect callback is called anytime the user is redirected to a callback URL (e.g. on signin or signout).

Since you didn't successfully log in (cancel), the Identity Provider returns an error to the only URL it is aware of, which is the login page (/auth/signin) but not signin_callback_url configured in Identity Provider. However, you can manually navigate to any path you want from /auth/signin page.

It seems like the returned error does not considered as a redirect.

@khteh
Copy link
Author

khteh commented Jun 13, 2023

It's due to the missing input param

useEffect(() => {
    const error = searchParams.get('error');

    // TODO: Handle case if manually navigated 

    if (error === "Callback") {
      router.push("/")
    } 
  }, [searchParams]);

@khteh khteh closed this as completed Jun 13, 2023
@arielconti10
Copy link

For me still not clear how can I make a proper handle of this kind of errors.
For example in my case I am using a custom OAuth Provider, if I reject to auth in the provider, the provider sends back this response to my application

[next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
https://next-auth.js.org/errors#oauth_callback_handler_error access_denied {
error: {
message: 'access_denied',
stack: 'Error: access_denied\n' +
'... lots of paths',
name: 'Error'
},
error_description: 'Resource owner rejected consent',
providerId: 'cleverbase',
message: 'access_denied'
}

and then my application is just being redirected to /auth/signin?error=Callback
How can I get this error messages / descriptions? I've tried tons of different stuff but the only thing I can get is the "Callback" which is not very good, we already have all the information being returned from the provider to my server, why I can't access this data?

@rahul-reveation
Copy link

I have a similar situation as @arielconti10 where I need to capture an error message returned by the provider and show the message to the user. The error=Callback is not enough.

@arielconti10 have you figured out any alternative?

@arielconti10
Copy link

@rahul-reveation not at all, I've just handled it as a generic error

@rahul-reveation
Copy link

Ok..that would not cut for us. We need to show the specific error.

@kodkroken
Copy link

kodkroken commented Jan 9, 2025

@rahul-reveation did you find a solution for this? I am currently trying to solve this issue as well using next-auth 4.24.10

@rahul-reveation
Copy link

Honestly, it's been more than one year and I don't remember if we ever found the solution

@arielconti10
Copy link

Me neither, I've bypassed it somehow but honestly I don't remember

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

No branches or pull requests

5 participants