auth-js icon indicating copy to clipboard operation
auth-js copied to clipboard

Auth state change events not firing on web page load

Open ProjectMoon opened this issue 3 years ago • 5 comments

Bug report

Describe the bug

When loading a web page with a supabase onAuthStateChange handler, one would expect the signed in event to fire once the page loads and the connection is established. But due to some recent code changes around how session restore is handled, this basically prevents any event handler from being registered. The SIGNED_IN event notification is fired as part of the Supabase client constructor.

To Reproduce

Steps to reproduce the behavior:

  1. Have an onAuthStateChanged handler.
  2. Load your script on a web page.

Expected behavior

The event handler fires.

Additional context

The problem is very apparent in a multi-page application/"regular website" with a Supabase connection. I think the issue is especially tied to this commit: https://github.com/supabase/gotrue-js/commit/3a670be41d6fa3d9c3022730f662b2ff03b57469

I was using 1.7.x before, and the event would fire when the web page loads.

Maybe some kind of event handler buffer could be introduced? Buffer auth events until a handler is added, then fire them all immediately.

ProjectMoon avatar Apr 27 '21 18:04 ProjectMoon

Hey @ProjectMoon - you're right - we had to re-eng this so that it would return from the constructor instead.

The problem is very apparent in a multi-page application/"regular website" with a Supabase connection

Can you clarify more about the problem? Not you should be able to inspect supabase.auth.session() immediately (like this), and this will return a logged-in session (if there is a valid session)

kiwicopple avatar Apr 28 '21 13:04 kiwicopple

The session exists and the user is logged in, yes. I have a very simple website where a user can log in to get a bit more information. Originally on Firebase, and before the recent changes, I relied on the auth state change event to fire so I could fetch and display the information/links/etc for logged in users. With this change, the event never fires and thus the page does not get updated for logged in users.

Is there a workaround maybe?

ProjectMoon avatar Apr 29 '21 15:04 ProjectMoon

With this change, the event never fires and thus the page does not get updated for logged in users

because session recovering now happens on constructor which is before any onAuthStateChange subscription.

For your use case, You can check for current session along with onAuthStateChange

supabase.auth.onAuthStateChange((event, session) => {
  // on event == SIGNED_IN, do s.th
})

if (supabase.auth.session()) {
  // user login, do s.th
}

phamhieu avatar Apr 30 '21 00:04 phamhieu

Here's the workaround function I have made for now:

type AuthChangeHandler = (event: supabase.AuthChangeEvent, session: supabase.Session | null) => void;

export function onAuthStateChange(client: supabase.SupabaseClient, callback: AuthChangeHandler) {
    document.addEventListener('DOMContentLoaded', function() {
        if (client.auth.session()) {
            callback('SIGNED_IN', client.auth.session());
        }
    });

    client.auth.onAuthStateChange((event, session) => {
        callback(event, session);
    });
}

ProjectMoon avatar May 01 '21 14:05 ProjectMoon

One year later is this workaround still necessary?

I'm trying to use Supabase again after about a year of absence and I found that following the examples given by the docs sometimes the events don't get fired especially when trying to use a third-party OAuth provider like GitHub.

The user is redirected back to my sign in page with an access token in the URL but then nothing happens. I expect the event to be fired and the user to get redirected to the dashboard on server side, but that's not the case.

milovangudelj avatar Sep 07 '22 13:09 milovangudelj

Hi @milovangudelj, it would be great if you can elaborate more on this point:

I expect the event to be fired and the user to get redirected to the dashboard on server side

The event only gets fire after the user is redirected to the dashboard. This is because we can only confirm that the user is signed in if the oauth callback is successful.

If the oauth callback is successful and the user is redirected to the dashboard, there should be a "SIGNED_IN" event fired which you can listen to using onAuthStateChange. Will be closing this issue for now but feel free to reopen if you wish to clarify and elaborate on your usecase.

kangmingtay avatar Sep 27 '22 07:09 kangmingtay