Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking changes: OAuth session token deleted from Cookies on page refresh after updating to 2.47.6 #1334

Closed
2 tasks done
tzhf opened this issue Dec 12, 2024 · 16 comments
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@tzhf
Copy link

tzhf commented Dec 12, 2024

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When using @supabase/supabase-js with Twitch as an OAuth provider, the auth-token is saved to localStorage upon redirection, but is immediately removed after a page refresh. This issue occurs after upgrading @supabase/supabase-js from 2.47.5 to 2.47.6 : #1334 (comment).
So i guess the culprit is here : https://github.com/supabase/auth-js/releases/tag/v2.67.0

After twitch login redirection, we get a session, which is stored in localStorage. At this point it's the expected behaviour.
But after a single page refresh, or a route redirection, the token is deleted from localStorage, the user is not authenticated, and the session does not persist. This behavior breaks the login flow, which worked correctly in previous versions.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

This works with 2.47.5 but not with 2.47.6:

useSupabase.ts composable :

import { createClient } from '@supabase/supabase-js'

export const useSupabase = () => {
  const config = useRuntimeConfig()
  return createClient(config.public.SUPABASE_URL, config.public.SUPABASE_KEY)
}

/pages/auth/redirect.vue :

const client = useSupabase()

onMounted(async () => {
  const { data: session, error } = await client.auth.getSession()
  if (session) {
    // Here we have a session, and the auth-token is stored in localStorage, it redirects successfully
    console.log('Session:', session) 
    return navigateTo(`/a_vue_page.vue`)
  } else {
    console.error('Session error:', error)
  }
}

/pages/a_vue_page.vue :

const client = useSupabase()
const getSession = await client.auth.getSession()
// The session is null, and the auth-token in localStorage has been deleted
console.log(getSession )

const handleTwitchLogin = () => {
  client.auth.signInWithOAuth({
    provider: 'twitch',
    options: { redirectTo: `${config.public.BASE_URL}/auth/redirect` },
  })
}

Expected behavior

After redirection, the session token should remain in localStorage and the user should stay authenticated.

System information

  • Nuxt: 3.13.2
  • Supabase-js: 2.47.5 & 2.47.6
  • Node.js: 18.20.4
@tzhf tzhf added the bug Something isn't working label Dec 12, 2024
@israel-lpz
Copy link

The same with
"@supabase/ssr": "0.5.2",
"@supabase/supabase-js": "2.47.6",
"next": "14.2.18",
"react": "18.3.1",

@blechatellier
Copy link

Running into similar issues with cookies, randomly disappear after upgrading to 2.47.6.

@philbaker4
Copy link

Same issues as above in a Next app router using @supabase/ssr

"next": "^15.1.0",
"@supabase/ssr": "^0.5.2",

# works
"@supabase/supabase-js": "^2.46.2",
# cookies dont persist across refresh
"@supabase/supabase-js": "^2.47.6",

@CognateCam
Copy link

"next": "^15.1.0",
"@supabase/ssr": "^0.5.2",

Using Next App Router with boilerplate Next.js SSR setup from Supabase docs and sb cookies are no longer created or are disappearing during authentication.

Version @supabase/supabase-js 2.47.5 works as intended.
Issue started after updating to @supabase/supabase-js 2.47.6

@adamfinchly
Copy link

Seeing the same issue
Version @supabase/supabase-js 2.47.5 works as intended.
Issue started after updating to @supabase/supabase-js 2.47.6

@Chippd
Copy link

Chippd commented Dec 13, 2024

I'm not going crazy then. Noticed about an hour after the release but thought I must be missing something since there was no issue here for it.

Had to pin to a few versions ago to get it working again. An insidious one if you have the ^ in your package.json, everything works locally (until you do an npm install of course) but then deploying the app to production installs the most recent version and so this pretty serious auth bug is in your app.

I had
"@supabase/supabase-js": "^2.46.1",
So fixed it by going to
"@supabase/supabase-js": "2.46.1",
I might not have needed to go back that far but that's what was working for me locally and when deployed.

@tzhf tzhf changed the title Possible breaking change between 2.45.4 and 2.47.6: Auth-token keeps getting deleted from localStorage on page refresh 2.47.6 Breaking changes: OAuth session token deleted on page refresh after upgrading to 2.47.6 Dec 13, 2024
@tzhf tzhf changed the title 2.47.6 Breaking changes: OAuth session token deleted on page refresh after upgrading to 2.47.6 Breaking changes: OAuth session token deleted from Cookies on page refresh after updating to 2.47.6 Dec 13, 2024
@MikeMcMahon
Copy link

MikeMcMahon commented Dec 13, 2024

I have been pulling my hair out ALL day on this, I dug into the logs and I see this now:

GoTrueClient@0 (2.67.0) 2024-12-13T03:44:06.283Z #_initialize() error detecting session from URL AuthPKCEGrantCodeExchangeError: Not a valid PKCE flow url.
    at SupabaseAuthClient._getSessionFromURL (models.mjs:1093:27)
    at async SupabaseAuthClient._initialize (models.mjs:178:41)
    at async eval (models.mjs:163:24)

I've tried even disabling PKCE flow and detect from URL. No matter what it is defaulted to true and it checks this pathway first and only.

Specifically this code from auth-js

  /**
   * IMPORTANT:
   * 1. Never throw in this method, as it is called from the constructor
   * 2. Never return a session from this method as it would be cached over
   *    the whole lifetime of the client
   */
  private async _initialize(): Promise<InitializeResult> {
    try {
      if (isBrowser() && this.detectSessionInUrl) {
        const { data, error } = await this._getSessionFromURL()
        if (error) {
          this._debug('#_initialize()', 'error detecting session from URL', error)

          if (isAuthImplicitGrantRedirectError(error)) {
            const errorCode = error.details?.code
            if (
              errorCode === 'identity_already_exists' ||
              errorCode === 'identity_not_found' ||
              errorCode === 'single_identity_not_deletable'
            ) {
              return { error }
            }
          }

          // failed login attempt via url,
          // remove old session as in verifyOtp, signUp and signInWith*
          await this._removeSession()

          return { error }
        }

From what I can see this.detectSessionInUrl is ALLLLWAYS set and so it tries the PKCE flow

      // Checks for mismatches between the flowType initialised in the client and the URL parameters
      if (!isRedirectFromImplicitGrantFlow && !isRedirectFromPKCEFlow) {
        if (this.flowType === 'implicit') {
          throw new AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.')
        } else if (this.flowType === 'pkce') {
          throw new AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.')
        } else {
          throw new AuthError('Invalid flow type.')
        }
      }

supabase/auth-js@089c687
supabase/auth-js@9f32d30

It's somewhere in one of those two commits but I'm not familiar enough with the codebase.

It's never able to detect that it's an implicit flow and those two commits dropped recently.

I was able to make it work in my testing by debugging and rewriting variables on the fly such that it would bypass the PKCE check. Then auth worked as normal.

@daveycodez
Copy link

OMG thank goodness I almost deleted ALL of my work today building a REST proxy because I thought I broke this :/

Downgrading to 2.45.4

D:

@ChuckJonas
Copy link

I just wasted my evening debugging this... 🤦

Traced it down to the same lines above with this errors:

GoTrueClient@1 (2.67.0) 2024-12-13T04:10:26.192Z #_initialize() error detecting session from URL AuthImplicitGrantRedirectError: Not a valid implicit grant flow url.

This fixed it for me.

export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey, {
  auth: {
    detectSessionInUrl: false,
  },
});

@daveycodez
Copy link

2.47.5 is the latest safest version, staying locked here til this is fixed Lol RIP

@ChuckJonas
Copy link

ChuckJonas commented Dec 13, 2024

2.47.5 is the latest safest version, staying locked here til this is fixed Lol RIP

I'm very upset with myself... I had a feeling it was just a "fresh release" issue about an hour ago and tried to downgrade, but forgot to remove the ^ 😮‍💨

@daveycodez
Copy link

daveycodez commented Dec 13, 2024

If Supabase team ever seeeees this where are the rate limiting options for Realtime that were promised months ago, or ways to disable public from spamming messages with anon key.. wassup. I was told it was a PR in review to go to dashboard a long time ago

@epavanello
Copy link

lost hours debugging and logging this bug 🤦🏻‍♂️ downgraded

@bobbybol
Copy link

Uff cost me an evening and a morning.. Reverted to 2.47.5, then found this issue report 🙃

@tzhf
Copy link
Author

tzhf commented Dec 13, 2024

Fix Merged #1337 and released: v2.47.7

@tzhf tzhf closed this as completed Dec 13, 2024
@nanderss
Copy link

""”””

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests