[GH-ISSUE #7554] feat(generic-oauth): add refreshTokenParams config option #10840

Open
opened 2026-04-13 07:12:28 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @ethan-huo on GitHub (Jan 22, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7554

Originally assigned to: @Paola3stefania on GitHub.

Problem

genericOAuth plugin supports authorizationUrlParams and tokenUrlParams for passing extra parameters, but there's no equivalent refreshTokenParams for the refresh token flow.

This is needed for OAuth providers that require additional parameters (like resource for audience-scoped JWT tokens) during token refresh.

Current behavior

When refreshing tokens, genericOAuth calls refreshAccessToken without any extraParams:

https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/plugins/generic-oauth/index.ts#L175-L183

return refreshAccessToken({
  refreshToken,
  options: {
    clientId: c.clientId,
    clientSecret: c.clientSecret,
  },
  authentication: c.authentication,
  tokenEndpoint: finalTokenUrl,
  // ❌ no extraParams
});

Expected behavior

Add refreshTokenParams config option that gets passed as extraParams to refreshAccessToken, similar to how tokenUrlParams works for token exchange.

Use case

When using an OAuth provider that issues JWT access tokens with audience/resource scoping (e.g., for Convex, Azure AD), the resource parameter must be included in both the initial token exchange AND the refresh token request. Currently:

  • authorizationUrlParams: { resource: "convex" } works
  • tokenUrlParams: { resource: "convex" } works
  • No way to pass resource during refresh → results in opaque token instead of JWT

Workaround

Currently requires a separate plugin to patch the provider's refreshAccessToken method after initialization:

export const refreshTokenFix = (): BetterAuthPlugin => ({
  id: "refresh-token-fix",
  init: (ctx) => {
    const provider = ctx.socialProviders.find((p) => p.id === "my-provider");
    if (provider) {
      provider.refreshAccessToken = async (refreshToken) => {
        // manual implementation with extraParams
      };
    }
    return {};
  },
});

Proposed change

// types.ts
+ /**
+  * Additional params to add to the refresh token request.
+  */
+ refreshTokenParams?: Record<string, string> | undefined;

// index.ts
return refreshAccessToken({
  refreshToken,
  options: { ... },
  authentication: c.authentication,
  tokenEndpoint: finalTokenUrl,
+ extraParams: c.refreshTokenParams,
});

This is a minimal, non-breaking change that completes the symmetry with authorizationUrlParams and tokenUrlParams.

Originally created by @ethan-huo on GitHub (Jan 22, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7554 Originally assigned to: @Paola3stefania on GitHub. ## Problem `genericOAuth` plugin supports `authorizationUrlParams` and `tokenUrlParams` for passing extra parameters, but there's no equivalent `refreshTokenParams` for the refresh token flow. This is needed for OAuth providers that require additional parameters (like `resource` for audience-scoped JWT tokens) during token refresh. ## Current behavior When refreshing tokens, `genericOAuth` calls `refreshAccessToken` without any `extraParams`: https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/plugins/generic-oauth/index.ts#L175-L183 ```typescript return refreshAccessToken({ refreshToken, options: { clientId: c.clientId, clientSecret: c.clientSecret, }, authentication: c.authentication, tokenEndpoint: finalTokenUrl, // ❌ no extraParams }); ``` ## Expected behavior Add `refreshTokenParams` config option that gets passed as `extraParams` to `refreshAccessToken`, similar to how `tokenUrlParams` works for token exchange. ## Use case When using an OAuth provider that issues JWT access tokens with audience/resource scoping (e.g., for Convex, Azure AD), the `resource` parameter must be included in both the initial token exchange AND the refresh token request. Currently: - ✅ `authorizationUrlParams: { resource: "convex" }` works - ✅ `tokenUrlParams: { resource: "convex" }` works - ❌ No way to pass `resource` during refresh → results in opaque token instead of JWT ## Workaround Currently requires a separate plugin to patch the provider's `refreshAccessToken` method after initialization: ```typescript export const refreshTokenFix = (): BetterAuthPlugin => ({ id: "refresh-token-fix", init: (ctx) => { const provider = ctx.socialProviders.find((p) => p.id === "my-provider"); if (provider) { provider.refreshAccessToken = async (refreshToken) => { // manual implementation with extraParams }; } return {}; }, }); ``` ## Proposed change ```diff // types.ts + /** + * Additional params to add to the refresh token request. + */ + refreshTokenParams?: Record<string, string> | undefined; // index.ts return refreshAccessToken({ refreshToken, options: { ... }, authentication: c.authentication, tokenEndpoint: finalTokenUrl, + extraParams: c.refreshTokenParams, }); ``` This is a minimal, non-breaking change that completes the symmetry with `authorizationUrlParams` and `tokenUrlParams`.
GiteaMirror added the oauth label 2026-04-13 07:12:28 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Jan 22, 2026):

Thank you for your detailed issue description regarding the addition of a refreshTokenParams config option for the genericOAuth plugin. Currently, the genericOAuth does not support passing extra parameters during the refresh token flow, leading to issues with certain OAuth providers that require specific parameters (like resource).

Your suggested changes to include the refreshTokenParams option are indeed valid, as it would align with how authorizationUrlParams and tokenUrlParams work, thereby maintaining symmetry [1]. While there isn't a confirmation on the timeline for this feature, I recommend keeping an eye on ongoing discussions in the GitHub repository.

For further assistance or potential development on this issue, you can tag members of the Better Auth team, Beka (@bekacru) and Max (@ping__), who might provide more insights.

Do you have any other questions or perhaps specific challenges you are facing while implementing this functionality?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3784194133 --> @better-auth-agent[bot] commented on GitHub (Jan 22, 2026): Thank you for your detailed issue description regarding the addition of a `refreshTokenParams` config option for the `genericOAuth` plugin. Currently, the `genericOAuth` does not support passing extra parameters during the refresh token flow, leading to issues with certain OAuth providers that require specific parameters (like `resource`). Your suggested changes to include the `refreshTokenParams` option are indeed valid, as it would align with how `authorizationUrlParams` and `tokenUrlParams` work, thereby maintaining symmetry [[1]](https://www.better-auth.com/docs/plugins/oauth-provider). While there isn't a confirmation on the timeline for this feature, I recommend keeping an eye on ongoing discussions in the GitHub repository. For further assistance or potential development on this issue, you can tag members of the Better Auth team, Beka (@bekacru) and Max (@ping__), who might provide more insights. Do you have any other questions or perhaps specific challenges you are facing while implementing this functionality? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@dosubot[bot] commented on GitHub (Jan 22, 2026):

Adding a refreshTokenParams config option to genericOAuth is technically straightforward, non-breaking, and fits the existing design. The core refreshAccessToken utility already supports extraParams, so you can simply extend GenericOAuthConfig to accept refreshTokenParams (as a record or function, just like tokenUrlParams), and pass it through to refreshAccessToken in the plugin’s refresh flow. This will let you send required parameters (like resource or scope) during token refresh for providers that need them, resolving real-world issues with JWT access tokens and audience scoping source source.

This change mirrors how authorizationUrlParams and tokenUrlParams work, and would not break existing configs. You’d just add an optional refreshTokenParams field to the config type and wire it into the refreshAccessToken call. No merged PRs currently address this, but there’s clear demand for it in user issues, especially for Microsoft Entra ID and similar providers source.

Until this is released, your plugin patch workaround is the best approach. When implementing, watch for provider-specific quirks (like parameter conflicts or required fields), and update docs/tests to cover the new option. This will make the plugin much more flexible for advanced OAuth scenarios.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:3784223810 --> @dosubot[bot] commented on GitHub (Jan 22, 2026): <!-- Answer --> Adding a refreshTokenParams config option to genericOAuth is technically straightforward, non-breaking, and fits the existing design. The core refreshAccessToken utility already supports extraParams, so you can simply extend GenericOAuthConfig to accept refreshTokenParams (as a record or function, just like tokenUrlParams), and pass it through to refreshAccessToken in the plugin’s refresh flow. This will let you send required parameters (like resource or scope) during token refresh for providers that need them, resolving real-world issues with JWT access tokens and audience scoping [source](https://github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/better-auth/src/plugins/generic-oauth/index.ts#L17-L171) [source](https://github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/core/src/oauth2/refresh-access-token.ts#L5-L124). This change mirrors how authorizationUrlParams and tokenUrlParams work, and would not break existing configs. You’d just add an optional refreshTokenParams field to the config type and wire it into the refreshAccessToken call. No merged PRs currently address this, but there’s clear demand for it in user issues, especially for Microsoft Entra ID and similar providers [source](https://github.com/better-auth/better-auth/issues/2769). Until this is released, your plugin patch workaround is the best approach. When implementing, watch for provider-specific quirks (like parameter conflicts or required fields), and update docs/tests to cover the new option. This will make the plugin much more flexible for advanced OAuth scenarios. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/b5403531-7669-4eaa-891a-0677f6015d74?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Adding%20a%20refreshTokenParams%20config%20option%20to%20genericOAuth%20is%20technically%20straightforward%2C%20non-breaking%2C%20and%20fits%20the%20existing%20design.%20The%20core%20refreshAccessToken%20utility%20already%20supports%20extraParams%2C%20so%20you%20can%20simply%20extend%20GenericOAuthConfig%20to%20accept%20refreshTokenParams%20%28as%20a%20record%20or%20function%2C%20just%20like%20tokenUrlParams%29%2C%20and%20pass%20it%20through%20to%20refreshAccessToken%20in%20the%20plugin%E2%80%99s%20refresh%20flow.%20This%20will%20let%20you%20send%20required%20parameters%20%28like%20resource%20or%20scope%29%20during%20token%20refresh%20for%20providers%20that%20need%20them%2C%20resolving%20real-world%20issues%20with%20JWT%20access%20tokens%20and%20audience%20scoping%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/better-auth/src/plugins/generic-oauth/index.ts%23L17-L171%29%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/core/src/oauth2/refresh-access-token.ts%23L5-L124%29.%0A%0AThis%20change%20mirrors%20how%20authorizationUrlParams%20and%20tokenUrlParams%20work%2C%20and%20would%20not%20break%20existing%20configs.%20You%E2%80%99d%20just%20add%20an%20optional%20refreshTokenParams%20field%20to%20the%20config%20type%20and%20wire%20it%20into%20the%20refreshAccessToken%20call.%20No%20merged%20PRs%20currently%20address%20this%2C%20but%20there%E2%80%99s%20clear%20demand%20for%20it%20in%20user%20issues%2C%20especially%20for%20Microsoft%20Entra%20ID%20and%20similar%20providers%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/2769%29.%0A%0AUntil%20this%20is%20released%2C%20your%20plugin%20patch%20workaround%20is%20the%20best%20approach.%20When%20implementing%2C%20watch%20for%20provider-specific%20quirks%20%28like%20parameter%20conflicts%20or%20required%20fields%29%2C%20and%20update%20docs/tests%20to%20cover%20the%20new%20option.%20This%20will%20make%20the%20plugin%20much%20more%20flexible%20for%20advanced%20OAuth%20scenarios.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/7554)
Author
Owner

@JoshWilkesQoria commented on GitHub (Feb 2, 2026):

I also have a use-case where I needed this functionality and I had opened a PR here #7660 which is pending a review

<!-- gh-comment-id:3832426208 --> @JoshWilkesQoria commented on GitHub (Feb 2, 2026): I also have a use-case where I needed this functionality and I had opened a PR here #7660 which is pending a review
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10840