Search code examples
next.jsoauthopenidnext-auth

Endless troubles with next-auth v4 and FacebookProvider


I've been trying to set up login with facebook feature with next-auth v4 and I keep running into some issues. Apart from the issues themselves what's really frustrating is the difficulty to reproduce problems - they seem as if they depend on so many factors that it's nearly impossible to take them all into account.

Anyway, I have a facebook developer app set up that's in 'development' app mode, so not live, therefore for now I'm only testing the feature with accounts that are within my developer organization (other developers, testers, etc).

1. The original problem

FacebookProvider({
  clientId: process.env.FACEBOOK_CLIENT_ID,
  clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
  userinfo: {
    url: 'https://graph.facebook.com/me',
    params: { fields: 'id,name,email,picture,first_name,last_name' },
    async request({ tokens, client, provider }) {
      const res = await client.userinfo(tokens.access_token, {
        params: provider.userinfo?.params
      });
      return res;
    }
  }
})

So yeah originally I used the userinfo function to call the facebook api and retrieve user data. Therefore, from my limited understanding of OAuth, I opted not to use id_token and OpenId extension of OAuth.

With this setup I was able to log in with my own facebook account and with every Test User that we have set up within the app. However, for some reason, whenever someone from my organization tried to log in they received an error

id_token detected in the response, you must use client.callback() instead of client.oauthCallback()

Googling this error and looking at endless github issues revealed nothing to me. Many people said to remove 'openid' from the 'scope' parameter, however I've never had it there in the first place. What's even more baffling is that it works for my account and the test users but not for anyone else's account (of which some are administrators and some are testers).

2. Another attempt

After this my line of reasoning was - ok, let's try to use id tokens, if they work for everyone - no problem, even better since it's one step less. So I added idToken: true to my config.

FacebookProvider({
  clientId: process.env.FACEBOOK_CLIENT_ID,
  clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
  idToken: true
}),

I've also experimented with adding authorization with different scopes such as

FacebookProvider({
  clientId: process.env.FACEBOOK_CLIENT_ID,
  clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
  idToken: true,
  authorization: {
    params: {
      scope: ['email', 'name']
    }
  }
}),

and also adding and removing 'openid' as a scope. I believe I've practically tried every single combination, all resulting with the same error:

[next-auth][error][OAUTH_CALLBACK_ERROR] https://next-auth.js.org/errors#oauth_callback_error id_token not present in TokenSet { error: TypeError: id_token not present in TokenSet at Client.validateIdToken (/app/node_modules/openid-client/lib/client.js:73

Kind of ironic, initially the error would suggest that I'm receiving an id token but not utilizing it, now that I wish to use it it says that it isn't there. Oh and with this setup at least the error is consistent - it crashes for every user (my account, test accounts, other people in the organization).

Does anyone know what's causing this behaviour, and what is the correct way to set this up? Could this be an issue with the developer app itself, or is my configuration to blame?

Thanks in advance :)

UPDATE: Since I'm running out of time with the project I'm implementing this in, I've decided to go back to using the Facebook JavaScript SDK (where everything works fine). I will keep this open in case someone else has the same problem, or if I decide to try and make next-auth work in the future.


Solution

  • Final update: I've given up on next-auth completely, used appropriate SDKs, and created the necessary abstractions myself. It turned out much easier and more maintainable than next-auth.