supabase / auth-helpers

A collection of framework specific Auth utilities for working with Supabase.
https://supabase.github.io/auth-helpers/
MIT License
892 stars 240 forks source link

`signOut` does not clear storage when session is invalid #778

Open chaichontat opened 1 month ago

chaichontat commented 1 month ago

Bug report

Describe the bug

supabase.auth.signOut does not remove storage/cookies when a session has been revoked. This meant the client retains a session and a (potentially) unexpired JWT.

This is a known issue in different auth repos and is recently fixed in auth-js: https://github.com/supabase/auth-js/pull/894. https://github.com/supabase/auth/issues/1550 https://github.com/supabase/auth/issues/1518 https://github.com/orgs/supabase/discussions/9327

To Reproduce

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

  1. Sign in using the supabase code template.
  2. Remove the session manually in the auth table using the supabase console.
  3. supabase.auth.signOut returns error: AuthApiError: Session from session_id claim in JWT does not exist and does not clear storage or cookies.

Expected behavior

supabase.auth.signOut should clear storage/cookies regardless of return from the supabase server.

System information

paule89123 commented 1 month ago

This is causing a big bug for me. If a user deletes their account, the app still thinks they're logged in. If they want to create a new account, I have to tell them to uninstall and re-install the app. This has resulted in my app receiving negative feedback.

Please can the supabase team look into this urgently?

justinianoleo commented 1 month ago

I'm having the same issue, the signOut function doesn't work when the token has expired or when i close the session in other device.

justinianoleo commented 1 month ago

I found a temp solution, you need to create a route handler and if the logout failed, you can redirect to this route: /auth/signout

export async function GET(req) { cookies().delete("your-cookie-name"); return NextResponse.redirect(new URL("/login", req.url), { status: 302, }); }

` const supabase = createClient(); const { data, error } = await supabase.auth.getUser();

if (error) {

const { error: erroruser } = await supabase.auth.signOut({
  revocation: true,
});

if (erroruser) {
  redirect("/auth/signout");
}

console.log("error signoyt", erroruser);

}`

chaichontat commented 1 month ago

This is my current mitigation by forcibly removing all cookies when signOut is called.

try {
    await event.locals.supabase.auth.signOut({ scope: "local" });
} catch (e) {
    console.error(e);
}
// https://github.com/supabase/auth-helpers/issues/778
event.cookies.getAll().forEach((cookie) => {
    event.cookies.delete(cookie.name, { path: "/" });
});