auth-helpers: @supabase/ssr@0.0.10 - supabase.auth.signOut() does not work

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

I migrated from SvelteKit Auth Helper to SSR Helper and everything seems fine except signing user out. supabase.auth.signOut() does nothing -user stay signed in.

In the Network tab I see a Request to https://my-supabase-instance.supabase.co/auth/v1/logout?scope=global with an empty Response.

To Reproduce

  1. Follow SSR docs at https://supabase.com/docs/guides/auth/server-side/migrating-to-ssr-from-auth-helpers?framework=sveltekit
  2. Add Sign Out button with function:
export let data: PageData;
let { supabase } = data;
$: ({ supabase } = data);

async function handleSignOut() {
  await supabase.auth.signOut();
  goto('/auth');
}

System information

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Comments: 24 (1 by maintainers)

Most upvoted comments

The client expects the function to only return a single cookie entry and deals with chunking itself, so I fixed the problem by removing the extra use of combineChunks() when creating the browser client

Thanks! This fixed my issue and sign out now works correctly.

I have tried both with and without combineChunks but it doesn’t make a difference for me. My log out works most of the time, but sometimes (and I can’t figure out why) it doesn’t log me out on the first attempt. *(But it always works on the second attempt.) I also have the onAuthStateChange code since I’m coming from auth-helpers. (You should add that to the ssr documentation btw because it’s really confusing for old and new people)

*EDIT: Sometimes it takes a few attempts or even a page refresh for log out to work

I think the reason the SSR documentation doesn’t explain this is because whoever wrote the docs assumed you already knew this or are coming from the auth-helpers.

The SSR docs even have depends('supabase:auth') but never bother to explain you need to add a corresponding invalidate('supabase:auth') to keep the page store in sync!

Not really sure what problem is caused by the cookies here, but that was not the problem. And changing that code to @briankintz could cause a problem for server side logout

see https://github.com/supabase/supabase/pull/19168#issuecomment-1841340674

If you reload the page after calling signOut it should work, but what I was wanting is the session to update automatically. If you followed the SSR setup tutorials then all you have left to is make sure you call invalidate("supabase:auth") to force the page store to stay in sync.

As long as you have the following layout.ts…

// src/routes/+layout.ts
import { createBrowserClient, isBrowser, parse, combineChunks } from "@supabase/ssr"
import type { LayoutLoad } from "./$types"
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from "$env/static/public"

export const load: LayoutLoad = async({ fetch, data, depends }) => {
    depends('supabase:auth')

    const supabase = createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
        global: {
            fetch,
        },
        cookies: {
            get(key) {
                if (!isBrowser()) {
                    return JSON.stringify(data.session)
                }

                const cookie = combineChunks(key, (name) => {
                    const cookies = parse(document.cookie)
                    return cookies[name]
                })
                return cookie
            }
        }
    })

    const {
        data: { session }
    } = await supabase.auth.getSession()

    return { supabase, session }
}

then in the page you just add the following:

the auth-helpers documentation contains code explaining how to do this https://supabase.com/docs/guides/auth/auth-helpers/sveltekit#setting-up-the-event-listener-on-the-client-side

<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import { invalidate } from '$app/navigation'
  import { onMount } from 'svelte'

  export let data

  let { supabase, session } = data
  $: ({ supabase, session } = data)

  onMount(() => {
    const {
      data: { subscription },
    } = supabase.auth.onAuthStateChange((event, _session) => {
      if (_session?.expires_at !== session?.expires_at) {
        invalidate('supabase:auth')
      }
    })

    return () => subscription.unsubscribe()
  });
</script>

<slot />

This solved my problem 😃 singOut and login and all the client side functions work now

I was running into the same issue in my next.js project so not sure if it applies but in case it does, what fixed it for me was placing the set and remove code blocks in my supabase server file like the example https://github.com/vercel/next.js/blob/canary/examples/with-supabase/utils/supabase/server.ts