next-auth: Error on missing `profileUrl` and/or `profile`

Describe the bug In the documentation, profileUrl and profile for custom providers are said to be not required in documentation but the application will crash if they are not given. This error is also the root of issue #209 as discovered by @ospira.

Steps to reproduce Steps to reproduce the behavior.

  • Create custom provider
  • Omit profileUrl and/or profile

Expected behavior Authentication to succeed and profile to be set to undefined.

Screenshots or error logs

[next-auth][error][oauth_get_access_token_error] [
  TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined
      at new NodeError (node:internal/errors:278:15)
      at validateString (node:internal/validators:123:11)
      at Url.parse (node:url:160:3)
      at Object.urlParse [as parse] (node:url:155:13)
      at exports.OAuth2._request (/Users/jackhedaya/Desktop/thoughtful-fish/node_modules/oauth/lib/oauth2.js:72:22)
      at /Users/jackhedaya/Desktop/thoughtful-fish/node_modules/next-auth/dist/server/lib/oauth/client.js:240:12
      at new Promise (<anonymous>)
      at exports.OAuth2.<anonymous> (/Users/jackhedaya/Desktop/thoughtful-fish/node_modules/next-auth/dist/server/lib/oauth/client.js:239:12)
     ...

Additional context Original custom Provider:

NextAuth(req, res, {
    providers: [
      {
        id: '[redacted]',
        name: '[redacted]',
        type: 'oauth',
        version: '2.0',
        accessTokenUrl: '[redacted]',
        requestTokenUrl: '[redacted]',
        authorizationUrl: `[redacted]`,
        clientId: process.env.CONSUMER_KEY,
        params: {
          grant_type: 'authorization_code',
        },
      },
    ],
    debug: true,
  })

Working custom provider:

NextAuth(req, res, {
    providers: [
      {
        id: '[redacted]',
        name: '[redacted]',
        type: 'oauth',
        version: '2.0',
        accessTokenUrl: '[redacted]',
        requestTokenUrl: '[redacted]',
        authorizationUrl: `[redacted]`,
        clientId: process.env.CONSUMER_KEY,
        params: {
          grant_type: 'authorization_code',
        },
        profileUrl: '[redacted]',
        profile: (p) => {
          return {
            id: p.userId
          }
        },
      },
    ],
    debug: true,
  })
  • 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

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 22 (10 by maintainers)

Most upvoted comments

Please have a look at this RFC for a new way of configuring a provider, with an optional profile! #1846

Related issue from ealier: https://github.com/nextauthjs/next-auth/issues/573.

In my case, for example, I am trying to implement Shopify admin login using their OAuth scheme. There is actually an endpoint that returns some information but it expects a custom X-Shopify-Access-Token header, and there is no way to customize profile GET request to send that.

It would be great to make profileUrl be actually optional, and/or allow per-provider customization of the request headers (and other details too).

Hmm I’m not sure if it’s fair to assume everyone is using a profile. Personally, I’m using a provider primarily for authentication rather than needing their actual user data. I use the user data as well, but I’m not sure it should be enforced by NextAuth.

@mcintyre94 yeah, I used https://api.notion.com/v1/users as the endpoint for profile Url, and then filter out the user we want from the response.

My workflow looks something like this

  1. Login with email
  2. Connect Notion (this executes the same flow as Login with Notion)
  3. I get all users of the workspace in the profile instead of a single user. Since I know the email of logged in user, I manually filter that user from these list of users, and update the user properties in my database.

Thanks for understanding! We are constantly thinking about how to provide a robust enough solution that is easy-to-use and covers enough use cases to be a worthy provider option addition.

I think some kind of a callback could work for getting tokens (id_token, refresh_token, access_token) and profile data:

...
async getProfile ({ url, headers, params, tokens }) {
  return { url, headers, params }
},
async getTokens ({ url, headers, params }) {
  return { url, headers, params }
},
...

Returning null for getProfile could mean that the user doesn’t want to get any data (that I think would cover a solution for this original issue) about the user. This way you could override most of the aspects, but we would still have control of the actual request.

This can be achieved in v4 by the following provider option:

userinfo: {
  request() {
    return {id: ""}
  }
}

A user id is expected to be returned, especially if you would use an adapter. You can set an empty string if you don’t care about this.

Sorry, I reopen this to track it differently from #1846 after all. 🙂. I will have a look at this as well, but the PR to implement #1846 was getting huge.

I’m running into the same issue as well. Setting up a custom provider - and we don’t need the profile as we’re only using it for authorization. Is there any workaround or setting to bypass this?

Since this is not a required field in the spec - can we simply not throw an error if the profileUrl is undefined, and instead just skip the profile fetch?