question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Improve OAuth provider configuration

See original GitHub issue

Summary of proposed feature Introducing a new way of configuring OAuth providers. With this proposal, we can provide granular control from basic (with the best defaults we can think of) to completely controlled hooks into the login flow. (The user would be able to do the actual fetch calls themselves. Hopefully, this will almost never would be necessary)

Here is an example:

export default function Auth0(options) {
  return {
    id: "auth0",
    name: "Auth0",
    authorization: `https://${options.domain}/authorize?grant_type=authorization_code&response_type=code&scope=openid%20email%20profile`,
    // Alternatively, you could pass an url and params
    // which will be combined for you for convinience.
    // authorization: {
    //   url: `https://${options.domain}/authorize`,
    //   params: {
    //     grant_type: "authorization_code",
    //     response_type: "code",
    //     scope: "openid email profile",
    //   },
    // },
    // Skips fetching user data. In some rare situations, you may not need this. See #1065
    userinfo: null,
    token: {
      url: `https://${options.domain}/oauth/token`,
      method: "POST",
      via: "header",
      // Complete control over how to get the userinfo.
      async request({ tokens }) {
        const response = await fetch("custom/endpoint/token", {
          headers: {
            Authorization: `Bearer ${tokens.access_token}`,
          },
        })
        return await response.json()
      },
    },
    profile(profile) {
      return {
        id: profile.sub,
        name: profile.nickname,
        email: profile.email,
        image: profile.picture,
      }
    },
    ...options,
  }
}

Purpose of proposed feature To simplify the configuration by reducing the number of required fields, but give full control at the same time, for advanced use cases.

Detail about proposed feature

So to sum it up, 3 new methods could be introduced, using a similar shape:

/** Any contextual information that makes the request useful, eg.: tokens in case of the token endpoint */
type RequestContext = any

type OAuthEndpoint = string | null | {
  url?: string
  method?: "POST" | "GET"
  /** How to pass the access token */
  via?: "header" | "body" | "query"
  /** Will be used as URL params if method is GET, or the body as x-url-form-encoded if POST*/
  params?: URLSearchParams | Record<string, unknown>
  request(context: RequestContext)?: Promise<any>
}

Potential problems As there are no conflicting configuration options, this could be implemented in a non-breaking way, meaning in theory we don’t have to wait until the next major version.

Describe any alternatives you’ve considered The current configuration is fragile since the OAuth spec can be interpreted differently, which often ends up with slightly too specific implementations, which has been hard to handle until now. The best solution was one-off configuration flags for certain providers, but in the long term, it introduced bloat in the code.

Additional context

Please indicate if you are willing and able to help implement the proposed feature. Could fit neatly into #1698, or a follow-up PR.

Related: #1065, #1642, #1605, #1607, #1756, #950

Please share your opinions!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:7
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
jackHedayacommented, May 21, 2021

I’m digging this proposal. I turned away from using NextAuth simply because the OAuth provider I was using did not fit the library but with fine tune control like this I would be interested in giving it another shot.

3reactions
Fronixcommented, Apr 25, 2021

I feel this would make next-auth a lot more flexible and allow support for pretty much any provider. It is usually the get token part that differs between providers with some using POST other GET, some using pkce and so on. This would make it much easier to let users customize every provider!

If I’m understanding correct parts like this wouldn’t be needed for providers that haven’t been added to next-auth? src/server/lib/oauth/client.js

  if (provider.id === 'reddit') {
    headers.Authorization = 'Basic ' + Buffer.from((provider.clientId + ':' + provider.clientSecret)).toString('base64')
  }


  if (provider.id === 'identity-server4' && !headers.Authorization) {
    headers.Authorization = `Bearer ${code}`
  }


  if (provider.protection.includes('pkce')) {
    params.code_verifier = codeVerifier
  }
Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC 9201 - Additional OAuth Parameters for Authentication ...
Additional OAuth Parameters for Authentication and Authorization for Constrained Environments (ACE) (RFC 9201, August 2022)
Read more >
RFC 6749: The OAuth 2.0 Authorization Framework
This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849. Status of This Memo This is an Internet Standards Track...
Read more >
Map of OAuth 2.0 Specs
RFC 6749 is the core OAuth 2.0 framework. This describes the roles (resource owner, client, authorization server, etc, described in more ...
Read more >
The complete guide to protecting your APIs with OAuth2 (part 1)
When you are using OAuth, you outsource user authentication and authorization to a central identity provider (IdP). Users sign in to the IdP...
Read more >
OAuth Authorization Flows - Salesforce Help
OAuth authorization flows grant a client application restricted access to protected resources on a resource server. Each OAuth flow offers a different ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found