RFC: Improve OAuth provider configuration
See original GitHub issueSummary 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:
- Created 2 years ago
- Reactions:7
- Comments:9 (4 by maintainers)
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.
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