nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
22.49k stars 2.98k forks source link

Google Provider TODO: Handle OIDC response body error #10731

Open INIRU opened 3 weeks ago

INIRU commented 3 weeks ago

Provider type

Google

Environment

 System:
    OS: macOS 14.4.1
    CPU: (11) arm64 Apple M3 Pro
    Memory: 127.47 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.7.3 - ~/.nvm/versions/node/v21.7.3/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v21.7.3/bin/npm
  Browsers:
    Safari: 17.4.1
  npmPackages:
    @auth/mongodb-adapter: ^2.6.0 => 2.6.0 
    next: ^14.2.1 => 14.2.1 
    next-auth: ^5.0.0-beta.16 => 5.0.0-beta.16 
    react: ^18.2.0 => 18.2.0 

Reproduction URL

https://github.com/TodayWantLook/TWL-NextJS/tree/developer/iniru

Describe the issue

스크린샷 2024-04-26 오전 12 33 15 스크린샷 2024-04-26 오전 12 33 17 스크린샷 2024-04-26 오전 12 33 22

I seem to be having some issues getting the callbackurl from Google. I have attached the error in the picture above.

How to reproduce

//env.local

DB_NAME = DB_NAME
DB_URL = DB_URL

NEXTAUTH_URL = https://todaywantlook.vercel.app
AUTH_SECRET = secret

AUTH_GOOGLE_ID = ''
AUTH_GOOGLE_SECRET = ''
스크린샷 2024-04-26 오전 12 38 10

After making the above settings, you should see a prompt to check the Server Error Log when you arrive at the login page.

Expected behavior

The callbackurl should be routed correctly and you should be able to receive the login user information to the callbackurl normally.

murilobd commented 2 weeks ago

I'm having the same issue (I've just tried with beta 17 and still the same).

ndom91 commented 2 weeks ago

So I'm not 100% sure about this, but google is setup as an OIDC provider which will auto-detect all the required URLs from their .well-known oIDC manifest, but you've hardcoded the authorihzation URL.

You can pass the same additional parameters that yuo're appending like this:

 providers: [
   GoogleProvider({
     authorization: {
       params: {
         prompt: "consent",
         access_type: "offline",
         response_type: "code"
       }
     }
   })
 ],

In addition, you can drop the NEXTAUTH_URL environment variable. It should be auto-detected on Vercel. If that doesn't help, the up-to-date version is called AUTH_URL btw

INIRU commented 2 weeks ago

Oh, thank you for helping me with my code. I'll check it out.

murilobd commented 2 weeks ago

I'm running the app on AWS Amplify (not sure on how different is from Vercel) and I noticed that, when I pass the AUTH_REDIRECT_PROXY_URL env variable, it succeeds on the login/register but it still redirects to localhost:3000.

INIRU commented 2 weeks ago

So I'm not 100% sure about this, but google is setup as an OIDC provider which will auto-detect all the required URLs from their .well-known oIDC manifest, but you've hardcoded the authorihzation URL.

You can pass the same additional parameters that yuo're appending like this:

 providers: [
   GoogleProvider({
     authorization: {
       params: {
         prompt: "consent",
         access_type: "offline",
         response_type: "code"
       }
     }
   })
 ],

In addition, you can drop the NEXTAUTH_URL environment variable. It should be auto-detected on Vercel. If that doesn't help, the up-to-date version is called AUTH_URL btw

I tried the fix as you suggested, but it didn't fix the problem. When I run it locally with npm run dev it logs in fine, but mysteriously when I push it up to the server, next-auth gives me an error.

ndom91 commented 2 weeks ago

@INIRU can you share that next-auth error?

@murilobd the AUTH_REDIRECT_PROXY_URL option is designed for proxying preview deploy's through your prod deploy so you can login with Google (for example) on your preview deploys (or other apps), see: https://authjs.dev/getting-started/deployment#securing-a-preview-deployment

ndom91 commented 2 weeks ago

@murilobd have yuo updated your callbackUrl in the Google / whatever OAUth provider dashboard? That's what tells the app where to redirect back to by default

INIRU commented 2 weeks ago

@ndom91

[GET][xxx] /api/auth/callback/google
error { error: 'invalid_client', error_description: 'Unauthorized' }
[GET][xxx] /api/auth/callback/google
[auth][error] CallbackRouteError: Read more at https://errors.authjs.dev#callbackrouteerror
[GET][xxx] /api/auth/callback/google
[auth][cause] Error: TODO: Handle OIDC response body error
    at ib (/var/task/.next/server/chunks/168.js:393:28075)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async iR (/var/task/.next/server/chunks/168.js:393:33995)
    at async iW (/var/task/.next/server/chunks/168.js:393:45324)
    at async iq (/var/task/.next/server/chunks/168.js:393:50193)
    at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:34801
    at async eS.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:25910)
    at async eS.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:36055)
    at async ei (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:25466)
    at async es.responseCache.get.routeKind (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:1026)
[GET][xxx] /api/auth/callback/google
[auth][details]: {
  "provider": "google"
}
[GET][500] /api/auth/error
/api/auth/error?error=Configuration&nxtPnextauth=error status=500
ndom91 commented 2 weeks ago

From that it seems like your clientId is either incorrect (copy and paste error maybe?) or just not being picked up. In order to infer it automatically, and not have to manually pass it to the Google() provider in your configuration, the environment variables have to be named like this:

AUTH_GOOGLE_ID
AUTH_GOOGLE_SECRET

Do you have that in place in your environment?

murilobd commented 2 weeks ago

@murilobd the AUTH_REDIRECT_PROXY_URL option is designed for proxying preview deploy's through your prod deploy so you can login with Google (for example) on your preview deploys (or other apps), see: https://authjs.dev/getting-started/deployment#securing-a-preview-deployment

Yes, I'm aware of that. But I thought maybe giving a try to bypass the "https://localhost:3000" and it worked partially. It stopped being redirected to localhost with queryParams error=Configuration (as it's happening with @INIRU )

@murilobd have yuo updated your callbackUrl in the Google / whatever OAUth provider dashboard? That's what tells the app where to redirect back to by default

Yes. I've triple checked the callbackUrl to be the good one (I even created a new credential without the localhost just to be sure).

What I've just tried was to set the redirect() callback and it's working fine when the login succeeds. But, when it fails (in case when the account is not linked with the oauth provider), it redirects to https://localhost:3000/login?error=OAuthAccountNotLinked

redirect({ url, baseUrl }) {
            const finalUrl = new URL(url, process.env.APP_URL || baseUrl).href;
            console.log(
                " ------------ xxxxxx redirect xxxxxxx --------------- ",
                "url: " + url,
                "baseUrl: " + baseUrl,
                "finalUrl: " + finalUrl
            );
            return finalUrl;
        }

The APP_URL is an env variable I created with the good hostname. From the console.log, indeed, the baseUrl is being considered as https://localhost:3000

murilobd commented 2 weeks ago

@ndom91 just tried removing the AUTH_REDIRECT_PROXY_URL and it fails right after starting the auth process and redirects to: https://localhost:3000/api/auth/error?error=Configuration

INIRU commented 2 weeks ago

From that it seems like your clientId is either incorrect (copy and paste error maybe?) or just not being picked up. In order to infer it automatically, and not have to manually pass it to the Google() provider in your configuration, the environment variables have to be named like this:

AUTH_GOOGLE_ID
AUTH_GOOGLE_SECRET

Do you have that in place in your environment?

@ndom91 Yes, It's already set up and passes well to Google OAuth. The error seems to be in the CallbackRouting part.

ndom91 commented 2 weeks ago

@murilobd the correct environment variable is AUTH_URL, give that a shot. The AUTH_REDIRECT_PROXY_URL may have avoided the initial error, but it enables a whoel different flow inside the core, it's not what you want. Please remove it and try AUTH_URL instead of APP_URL :pray:

EDIT: Also small sidenote, to get that log output it seems like yuo want, you can use console.table or add \n to the end of each line so the console.log prints a new line

ndom91 commented 2 weeks ago

@ndom91 Yes, It's already set up and passes well to Google OAuth. The error seems to be in the CallbackRouting part.

Hmm well one way or another, google is telling us that the client_id it's receiving from you is invalid. I'd check the Google OAuth dashboard, maybe there's some more info there or in the worst case, I'd just generate a new clientId/clientSecret from Google

murilobd commented 2 weeks ago

The error seems to be in the CallbackRouting part.

I do suspect that's it too!

INIRU commented 2 weeks ago

image

my vercel env settings

murilobd commented 2 weeks ago

@murilobd the correct environment variable is AUTH_URL, give that a shot. The AUTH_REDIRECT_PROXY_URL may have avoided the initial error, but it enables a whoel different flow inside the core, it's not what you want. Please remove it and try AUTH_URL instead of APP_URL 🙏

@ndom91 When I set AUTH_URL, I have this error, simply by trying to access the webapp (and that's why I created the APP_URL)

image

murilobd commented 2 weeks ago

@ndom91 do you know if it's normal, when running the app on aws amplify, to have the network set as localhost? image

I'm asking this because, maybe all the redirects to localhost are because of that?

ndom91 commented 2 weeks ago

Yeah so that's the default thing your node process running next.js will expose. So your node process is running on a VM or container or whatever in Amplify and its exposing the applicaiotn at localhost:3000. Then Amplify will put a reverse proxy in front of that node process which will terminate and negotiate the SSL/TLS connection and accept traffic at https://app-123.aws.amplify.com (or whatever) and pass that traffic onto the node process in the container at localhost:3000. So yeah that part is fine :+1:

But also, the fact that that reverse proxy is in the way, is why your application doesn't know anything about the final URL and you need to tell it via AUTH_URL. But also, that reminds me (!), you'll also need to enable the trustHost configuration option to tell next.js / auth.js to trust the URL that that reverse proxy tells the node process (via the X-Forwarded-Host header it appends to requests when handing the request off to the node process) (Docs)

So long story short, try also adding trustHost: true to your auth.js config, or adding the AUTH_TRUST_HOST=true env var to your environment

Sidenote: In real life there's multiple reverse proxies / load balancers / CDN's in between you and the node process running your node.js app in an AWS container in amplify or whatever.

Nuno111 commented 2 weeks ago

Getting the same issue here.

I've got the same setup for github and google, github works fine but google gives me the invalid_client error and cause HANDLE OIDC response body error.

I've tripled checked, compared and searched by string, the clientId is 100% correct.

This is not new on my end, haven't been able to use google sign in since i setup next auth

image
murilobd commented 2 weeks ago

Yeah so that's the default thing your node process running next.js will expose. So your node process is running on a VM or container or whatever in Amplify and its exposing the applicaiotn at localhost:3000. Then Amplify will put a reverse proxy in front of that node process which will terminal SSL and accept traffic at https://app-123.aws.amplify.com (or whatever) and pass that traffic onto the node process in the container at localhost:3000. SO yeah that part is fine 👍

Thank you for the very clear explanation on how it works! I suspected it was, indeed, a reverse proxy, but just would like to confirm that authjs wasn't doing anything related to that.

So long story short, try also adding trustHost: true to your auth.js config, or adding the AUTH_TRUST_HOST=true env var to your environment

@ndom91 this is enabled. If I remove that configuration, I receive an error from authjs

ndom91 commented 2 weeks ago

Hmm very weird, but that error object is coming from Google, so something seems wrong there as well. Maybe it's with what we send them, but the Google provider in our example app still works (https://next-auth-example.vercel.app/auth/signin) using next-auth@5.0.0-beta.17.

image

image

Where that o.processAuthorizationCodeOpenIDResponse() is from panva's oauth4webapi library, see docs.

@Nuno111 Can you provide some more some more details about your setup? auth.ts configuration, versions of pkg and next, etc. :pray:

Nuno111 commented 2 weeks ago

Sure thing @ndom91

Here's some screenshots with info

auth.ts callbacks has some logic, but when using google it doens't even reach the callbacks, for github all works fine, thats why i didn't bother showing that logic here

I've tried the trusthost: true in auth.ts but still getting same issue

image image image image
INIRU commented 2 weeks ago

Strangely, it's been solved by recreating the Oauth ID.

Nuno111 commented 2 weeks ago

Didn't fix it for me, same issue unfortunately!

Nuno111 commented 2 weeks ago

@ndom91

I dug a little deeper and it seems the codeGrantResponse is not authorized before making the proccesAuthorizationCodeOpenIDResponse function call,

image image
ndom91 commented 1 week ago

@Nuno111 I see yuo're using next-auth@5.0.0-beta.4, have you tried the latest -beta.17?

murilobd commented 6 days ago

On next-auth@5.0.0-beta.17 I'm still facing the same issue, being redirected to https://localhost:3000 when authentication fails