Facebook oauth_code_verification_failed due to missing code_challenge #81

Closed
opened 2026-03-13 07:32:17 -05:00 by GiteaMirror · 9 comments
Owner

Originally created by @PawelPotempa on GitHub (Oct 15, 2024).

Describe the bug:

When using the library to authenticate via Facebook OAuth with PKCE, the token exchange step fails with the error: oauth_code_verification_failed. The error message indicates that the code_verifier is provided without a corresponding code_challenge in the authorization request, causing the OAuth process to fail.

To Reproduce:

  • Set up Facebook OAuth in the project.
  • Initiate the OAuth flow by redirecting to the Facebook login page.
  • After the user logs in and the authorization code is returned, the library attempts to exchange the code for access tokens.
  • The process fails with the error: oauth_code_verification_failed.

Expected behavior:

It should successfully handle the PKCE flow, ensuring that both the code_verifier and code_challenge are correctly sent and validated. The access token should be retrieved after the authorization code is exchanged.

Additional context:

Error message received during the token exchange:

{ 
  error: { 
    message: 'code_verifier param is provided without a code_challenge in authorization request.',
    type: 'OAuthException',
    code: 1,
    fbtrace_id: 'AiVg2G-HnpatNZDjjXMWGXo'
  },
  status: 400,
  statusText: 'Bad Request'
}
Originally created by @PawelPotempa on GitHub (Oct 15, 2024). **Describe the bug:** When using the library to authenticate via Facebook OAuth with PKCE, the token exchange step fails with the error: oauth_code_verification_failed. The error message indicates that the code_verifier is provided without a corresponding code_challenge in the authorization request, causing the OAuth process to fail. **To Reproduce:** - Set up Facebook OAuth in the project. - Initiate the OAuth flow by redirecting to the Facebook login page. - After the user logs in and the authorization code is returned, the library attempts to exchange the code for access tokens. - The process fails with the error: oauth_code_verification_failed. **Expected behavior:** It should successfully handle the PKCE flow, ensuring that both the code_verifier and code_challenge are correctly sent and validated. The access token should be retrieved after the authorization code is exchanged. **Additional context:** Error message received during the token exchange: ``` { error: { message: 'code_verifier param is provided without a code_challenge in authorization request.', type: 'OAuthException', code: 1, fbtrace_id: 'AiVg2G-HnpatNZDjjXMWGXo' }, status: 400, statusText: 'Bad Request' } ```
Author
Owner

@Bekacru commented on GitHub (Oct 16, 2024):

hey can you please check if this is resolved on the beta release better-auth@beta

@Bekacru commented on GitHub (Oct 16, 2024): hey can you please check if this is resolved on the beta release `better-auth@beta`
Author
Owner

@PawelPotempa commented on GitHub (Oct 16, 2024):

I've checked and it works - however, the account created comes with emailVerified: false, which I believe is intended (as far as I remember facebook isn't considered a trusted provider). That brings up a question though - what's the correct flow here to send the verification email? Can we intercept the oauth authorization success to send a verification email to the user?

@PawelPotempa commented on GitHub (Oct 16, 2024): I've checked and it works - however, the account created comes with `emailVerified: false`, which I believe is intended (as far as I remember facebook isn't considered a trusted provider). That brings up a question though - what's the correct flow here to send the verification email? Can we intercept the oauth authorization success to send a verification email to the user?
Author
Owner

@Bekacru commented on GitHub (Oct 16, 2024):

good question. we already support sending email verification on signup for email & password. we should support for oauth signups too. Feel free to open another issue. For now you can send using database hooks

https://www.better-auth.com/docs/concepts/database#database-hooks

before or after the user creation check if the email isn't verified and send email verification

@Bekacru commented on GitHub (Oct 16, 2024): good question. we already support sending email verification on signup for email & password. we should support for oauth signups too. Feel free to open another issue. For now you can send using database hooks https://www.better-auth.com/docs/concepts/database#database-hooks before or after the user creation check if the email isn't verified and send email verification
Author
Owner

@PawelPotempa commented on GitHub (Oct 16, 2024):

Before I open another issue - it seems the problem is either a bit more complex, or my implementation makes no sense. Here's a quick and unpolished code:

databaseHooks: {
        account: {
            create: {
                after: async (account) => {
                    if (account.providerId !== "credential") {
                        const user = await db.query.user.findFirst({
                            where: (user, { eq }) => eq(user.id, account.userId)
                        });

                        if (!user?.emailVerified && user) {
                            await auth.api.sendVerificationEmail({
                                body: {
                                    email: user.email,
                                },
                            });
                        }
                    }
                }
            },
        }
    },

The email with verification is being sent just fine, but the /verify-email api route doesn't work properly. The url looks fine:
http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InB3cG90ZW1wYUBnbWFpbC5jb20iLCJhdWQiOlsicHdwb3RlbXBhQGdtYWlsLmNvbSJdLCJzdWIiOiJ2ZXJpZnktZW1haWwiLCJpc3MiOiJiZXR0ZXItYXV0aCIsImV4cCI6MTcyOTExMDI3NSwiaWF0IjoxNzI5MTA2Njc1fQ.Vp4HZFRdLWMavZ8nZHLsuQRnuG1u6HRvJ-ILBkQ0H-I&callbackURL=http://localhost:3000/user-panel#_=_

The response I get is:
{"message":"Account not found"}.

I'm currently on: 0.4.10-beta.9

Tried on the newest 0.4.11 too, but an entirely different issue happens there (despite the #189 being merged to it) - can't register with Facebook yet again.

{ error: Better Auth
   { message:
      'code_verifier param is provided without a code_challenge in\n authorization request.',
      type: 'OAuthException',
      code: 1,
      fbtrace_id: 'AHjYbTBx2iKGufQL2GHupk3' },
  status: 400,
  statusText: 'Bad Request' }
@PawelPotempa commented on GitHub (Oct 16, 2024): Before I open another issue - it seems the problem is either a bit more complex, or my implementation makes no sense. Here's a quick and unpolished code: ``` databaseHooks: { account: { create: { after: async (account) => { if (account.providerId !== "credential") { const user = await db.query.user.findFirst({ where: (user, { eq }) => eq(user.id, account.userId) }); if (!user?.emailVerified && user) { await auth.api.sendVerificationEmail({ body: { email: user.email, }, }); } } } }, } }, ``` The email with verification is being sent just fine, but the /verify-email api route doesn't work properly. The url looks fine: `http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InB3cG90ZW1wYUBnbWFpbC5jb20iLCJhdWQiOlsicHdwb3RlbXBhQGdtYWlsLmNvbSJdLCJzdWIiOiJ2ZXJpZnktZW1haWwiLCJpc3MiOiJiZXR0ZXItYXV0aCIsImV4cCI6MTcyOTExMDI3NSwiaWF0IjoxNzI5MTA2Njc1fQ.Vp4HZFRdLWMavZ8nZHLsuQRnuG1u6HRvJ-ILBkQ0H-I&callbackURL=http://localhost:3000/user-panel#_=_` The response I get is: `{"message":"Account not found"}`. I'm currently on: `0.4.10-beta.9` Tried on the newest `0.4.11` too, but an entirely different issue happens there (despite the #189 being merged to it) - can't register with Facebook yet again. ``` { error: Better Auth { message: 'code_verifier param is provided without a code_challenge in\n authorization request.', type: 'OAuthException', code: 1, fbtrace_id: 'AHjYbTBx2iKGufQL2GHupk3' }, status: 400, statusText: 'Bad Request' } ```
Author
Owner

@Bekacru commented on GitHub (Oct 16, 2024):

regarding facebook it should be fixed. please confirm me. try 0.4.12-beta.1

@Bekacru commented on GitHub (Oct 16, 2024): regarding facebook it should be fixed. please confirm me. try `0.4.12-beta.1`
Author
Owner

@PawelPotempa commented on GitHub (Oct 16, 2024):

Yep, can confirm - facebook works fine again in 0.4.12-beta.1. The email verification error persists.

@PawelPotempa commented on GitHub (Oct 16, 2024): Yep, can confirm - facebook works fine again in `0.4.12-beta.1`. The email verification error persists.
Author
Owner

@Bekacru commented on GitHub (Oct 16, 2024):

Yep, can confirm - facebook works fine again in 0.4.12-beta.1. The email verification error persists.

For the email verification issue, try0.4.12-beta.2 And unless you specfically don't want to send verification on credential you should send on user.create instead.

@Bekacru commented on GitHub (Oct 16, 2024): > Yep, can confirm - facebook works fine again in `0.4.12-beta.1`. The email verification error persists. For the email verification issue, try`0.4.12-beta.2` And unless you specfically don't want to send verification on credential you should send on `user.create` instead.
Author
Owner

@PawelPotempa commented on GitHub (Oct 16, 2024):

Also can confirm, works perfectly fine now. Thanks!

You're absolutely right, I just kept using sendEmailVerificationOnSignUp: true so it did send the verification email for credentials anyway, but I guess it makes perfect sense to disable it and use just the hook instead.

Just a quick heads up - though that should most likely be another issue as well - if we have credentials account and wanna link a facebook account with the same email to it - it doesn't work. Linking Google account worked just fine. No visible errors anywhere, so nothing to share here.

@PawelPotempa commented on GitHub (Oct 16, 2024): Also can confirm, works perfectly fine now. Thanks! You're absolutely right, I just kept using `sendEmailVerificationOnSignUp: true` so it did send the verification email for credentials anyway, but I guess it makes perfect sense to disable it and use just the hook instead. Just a quick heads up - though that should most likely be another issue as well - if we have credentials account and wanna link a facebook account with the same email to it - it doesn't work. Linking Google account worked just fine. No visible errors anywhere, so nothing to share here.
Author
Owner

@Bekacru commented on GitHub (Oct 17, 2024):

if emailVerified isn't returned or if it's false, the account won't be linked. On google case it's always assumed verified.

@Bekacru commented on GitHub (Oct 17, 2024): if emailVerified isn't returned or if it's false, the account won't be linked. On google case it's always assumed verified.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#81