GitHub social provider sign-in refresh_token and refresh_token_expires_in missing #1416

Closed
opened 2026-03-13 08:38:59 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @0xCodeMaieutics on GitHub (Jun 25, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Steps:

  1. Setup GitHub provider
  2. Sign in
  3. Check database for missing properties

Current vs. Expected behavior

Current: better-auth does not store refresh_token and refresh_token_expires_in when signing in with GtiHub.

Expected: better-auth should store the properties when signing in with GtiHub.

What version of Better Auth are you using?

1.2.8

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6000
  Available memory (MB): 16384
  Available CPU cores: 10
Binaries:
  Node: 22.13.0
  npm: 10.9.2
  Yarn: 1.22.22
  pnpm: 9.4.0
Relevant Packages:
  next: 15.3.0
  eslint-config-next: N/A
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

export const auth = betterAuth({
  appName: "CodeClarify.ai",
  database: prismaAdapter(prisma, {
    provider: "postgresql",
  }),
  socialProviders: {
    github: {
      clientId: env.GITHUB_CLIENT_ID,
      clientSecret: env.GITHUB_CLIENT_SECRET,
      scope: ["user:email", "read:org"],

    },
  },
  user: {
    additionalFields: {
      username: {
        type: "string",
        required: false,
        defaultValue: "",
      },
    },
  },
  databaseHooks: {
    account: {
      create: {
        after: async ({ userId, accountId, accessToken }) => {
          if (!accessToken) return;
          const user = await githubClient.getUser(accessToken);
          await prisma.user.update({
            where: {
              id: userId,
            },
            data: {
              username: user.login,
            },
          });
        },
      },
    },
  },
  onAPIError: {
    throw: true,
    onError: (error, ctx) => {
      console.error("Auth error:", error);
    },
    errorURL: "/auth/error",
  },
});

Additional context

Originally created by @0xCodeMaieutics on GitHub (Jun 25, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Steps: 1. Setup GitHub provider 2. Sign in 3. Check database for missing properties ### Current vs. Expected behavior Current: `better-auth` does not store `refresh_token` and `refresh_token_expires_in` when signing in with GtiHub. Expected: `better-auth` should store the properties when signing in with GtiHub. ### What version of Better Auth are you using? 1.2.8 ### Provide environment information ```bash Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6000 Available memory (MB): 16384 Available CPU cores: 10 Binaries: Node: 22.13.0 npm: 10.9.2 Yarn: 1.22.22 pnpm: 9.4.0 Relevant Packages: next: 15.3.0 eslint-config-next: N/A react: 19.1.0 react-dom: 19.1.0 typescript: 5.8.2 Next.js Config: output: N/A ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript export const auth = betterAuth({ appName: "CodeClarify.ai", database: prismaAdapter(prisma, { provider: "postgresql", }), socialProviders: { github: { clientId: env.GITHUB_CLIENT_ID, clientSecret: env.GITHUB_CLIENT_SECRET, scope: ["user:email", "read:org"], }, }, user: { additionalFields: { username: { type: "string", required: false, defaultValue: "", }, }, }, databaseHooks: { account: { create: { after: async ({ userId, accountId, accessToken }) => { if (!accessToken) return; const user = await githubClient.getUser(accessToken); await prisma.user.update({ where: { id: userId, }, data: { username: user.login, }, }); }, }, }, }, onAPIError: { throw: true, onError: (error, ctx) => { console.error("Auth error:", error); }, errorURL: "/auth/error", }, }); ``` ### Additional context - `refresh_token_expires_in` missing here: https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/oauth2/utils.ts#L13
GiteaMirror added the bug label 2026-03-13 08:38:59 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 25, 2025):

This is expected behavior: GitHub's OAuth2 implementation does not issue a refresh_token or refresh_token_expires_in in standard web application flows, so better-auth cannot store them. The token extraction logic in better-auth is generic and will store these fields if the provider returns them, but GitHub simply does not provide them in most cases. There is no bug or omission in better-auth's code—if GitHub ever returns these fields, they will be picked up automatically by the framework. If you need long-lived tokens, you may need to explore GitHub Apps or other authentication strategies, as standard OAuth2 for GitHub does not support refresh tokens for typical web sign-ins.
You can see this in the code and provider logic:
getOAuth2Tokens in oauth2/utils.ts
GitHub provider implementation

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jun 25, 2025): <!-- Answer --> This is expected behavior: GitHub's OAuth2 implementation does not issue a refresh_token or refresh_token_expires_in in standard web application flows, so better-auth cannot store them. The token extraction logic in better-auth is generic and will store these fields if the provider returns them, but GitHub simply does not provide them in most cases. There is no bug or omission in better-auth's code—if GitHub ever returns these fields, they will be picked up automatically by the framework. If you need long-lived tokens, you may need to explore GitHub Apps or other authentication strategies, as standard OAuth2 for GitHub does not support refresh tokens for typical web sign-ins. You can see this in the code and provider logic: [getOAuth2Tokens in oauth2/utils.ts](https://github.com/better-auth/better-auth/blob/048914fbaf99469f8756f0570c632c5fbadbd8ed/packages/better-auth/src/oauth2/utils.ts) [GitHub provider implementation](https://github.com/better-auth/better-auth/blob/048914fbaf99469f8756f0570c632c5fbadbd8ed/packages/better-auth/src/social-providers/github.ts) <!-- 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/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/2ac7f607-0ab9-4aad-91af-1f1f752e2467?feedback_type=other)</sup>&nbsp;&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/3166)
Author
Owner

@0xCodeMaieutics commented on GitHub (Jun 25, 2025):

Opened a PR for refresh_token_expires_in field: #3167

@0xCodeMaieutics commented on GitHub (Jun 25, 2025): Opened a PR for `refresh_token_expires_in` field: #3167
Author
Owner

@ping-maxwell commented on GitHub (Jul 8, 2025):

@0xCodeMaieutics For regular OAuth apps, GitHub issues access tokens that remain valid indefinitely unless the user revokes them, the app revokes them, or they go unused for a year. There’s no need for a refresh token because the access token doesn’t expire on a short interval like Google or Discord

@ping-maxwell commented on GitHub (Jul 8, 2025): @0xCodeMaieutics For regular OAuth apps, GitHub issues access tokens that remain valid indefinitely unless the user revokes them, the app revokes them, or they go unused for a year. There’s no need for a refresh token because the access token doesn’t expire on a short interval like Google or Discord
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1416