nextauthjs / nextauthjs/next-auth

Google provider failing to get proper providerAccountId

Open
#12,808 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug providers triage
Dominant language
TypeScript
Stars
28.4k
Forks
4k
PR merge metrics
No merged PRs in 30d

Description

Provider type

Google

Environment
System:
    OS: Linux 6.11 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
    CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900K
    Memory: 22.98 GB / 31.05 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  Binaries:
    Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
    npm: 10.9.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
    pnpm: 9.8.0 - ~/.local/share/pnpm/pnpm
  Browsers:
    Chrome: 134.0.6998.165
  npmPackages:
    @auth/d1-adapter: ^1.8.0 => 1.8.0 
    @auth/sveltekit: ^1.8.0 => 1.8.0
Reproduction URL

https://github.com/lucas-subli/authjs-12807

Describe the issue

When using Google Provider the library seems to fail in generating a proper providerAccountId, issuing a new one for every login. Which causes weird behavior from the second login onwards.

How to reproduce
  • Configure a project using the database session option and the Google Provider.
  • Do NOT use the prompt: "consent" option
  • Turn debug on
  • Now login for the first time
  • Go into the database, and take note your account providerAccountId. We will use it later.
  • Logout
  • Login again
  • Notice that you will get OAuthAccountNotLinked
  • Search in the debug logs for authorization result -> account -> providerAccountId
  • Notice how it does not match the providerAccountId on the database
  • Since the providerAccountIds do not match the code fails to find a matching account for that provider, but since the user exists it assumes it was created with another provider, causing the issue.
Expected behavior
  • The providerAccountId should match the existing account
  • The second login should work properly
Workaround to make everything work

Expected behavior can be achieved by using the following configuration:

Google({
  (...)
  profile: async (profile) => {
    return {
      ...profile,
      id: profile.sub, // If you don't do this, signing in, then signing out, then signing in again will NOT work
  };
}),
Why the workaround works?

The above seems to map the userFromProfile.id here properly to the Google sub on the Oauth return causing it to be consistent across executions and work as expected.

What would be a possible solution?
  • The solution seems to be for the library to map (for Google) the profile ID to the User sub from Google
  • Probably this file should have a default profile configuration such as:
return {
  id: "google",
  name: "Google",
  type: "oidc",
  issuer: "https://accounts.google.com",
  async profile(profile) {
    return {
      id: profile.sub,
      name: profile.name,
      email: profile.email,
      image: profile.picture,
      emailVerified: profile.email_verified,
    }
  },
  style: {
    brandColor: "#1a73e8",
  },
  options,
}
  • The above was NOT tested and is merely a suggestion based on what I found in my debugging. I lack the necessary knowledge of this codebase to propose a proper solution. Take this as a mere starting point for what I THINK is the cause.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/core/src/providers/google.ts and the account lookup in packages/core/src/lib/actions/callback/oauth/callback.ts, then reproduce the second-login failure using the linked reproduction project. Compare the returned providerAccountId with the stored account value and verify the behavior with database sessions and Google without prompt: "consent". Done means repeated sign-ins resolve the existing Google account without OAuthAccountNotLinked.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authentication
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.