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

supabase.auth.logout() throws "Invalid user" error. #15

Closed
thorwebdev opened this issue Aug 8, 2020 · 16 comments · Fixed by #50
Closed

supabase.auth.logout() throws "Invalid user" error. #15

thorwebdev opened this issue Aug 8, 2020 · 16 comments · Fixed by #50

Comments

@thorwebdev
Copy link
Member

I found this to only happen sometimes, but couldn't figure out why:
image

@kiwicopple have you seen this before?

@kiwicopple
Copy link
Member

The only thing I could think is that the token is expired when you try to log out. A couple of questions:

  • Is the browser left open, and then you try to log out after >3 hours?
  • There is a logout network call about 10 requests above the erroneous network call. Did you hit the button twice? Perhaps you're logged out already and the redirect to the home screen failed for some reason

@thorwebdev
Copy link
Member Author

thorwebdev commented Aug 11, 2020

Is the browser left open, and then you try to log out after >3 hours?

I'm able to reproduce this multiple times within a time window of less than 1h

There is a logout network call about 10 requests above the erroneous network call. Did you hit the button twice? Perhaps you're logged out already and the redirect to the home screen failed for some reason

Yes, there are times where the logout call is successful. You can see in the network comms though that after the logout there is a login (token?grant_types=password, right?). So don't think it's that.

@awalias
Copy link
Member

awalias commented Aug 11, 2020

@thorwebdev are you just using the OG slack clone example here?

@thorwebdev
Copy link
Member Author

@awalias yes, I'm able to observe this also on the official https://supabase-slack-clone.vercel.app/

slack-clone-logout-error

@awalias
Copy link
Member

awalias commented Aug 13, 2020

@awalias
Copy link
Member

awalias commented Aug 13, 2020

issue is when a user instantiates two or more supabase clients - fix is to always check localStorage before adding this.accessToken as an auth bearer token to see if there is one on the browser

@phamhieu
Copy link
Member

It's gotrue logout api bug. The cookie is cleared before calling getUserFromClaims .

Screenshot 2020-08-17 at 10 50 15 AM

Screenshot 2020-08-17 at 10 51 54 AM
Screenshot 2020-08-17 at 10 52 23 AM

@phamhieu
Copy link
Member

phamhieu commented Aug 17, 2020

On slack-clone app, after an Invalid user error fires, I can login and logout successfully!!! no idea why the logout can goes through getUserFromClaims check

However the next login/logout will trigger Invalid user error again.

@awalias
Copy link
Member

awalias commented Aug 18, 2020

Oh we didn't update this issue after meeting @thorwebdev last week about this.

The issue here is that Slack-clone app uses two different supabase client instances, and supabase-js only reads from local storage on initiation, and manages it's own state of which user is logged in after that point - so multiple clients can easily get out of sync on current user state

Our options here are:

  1. supabase-js should check local storage before each call to see if there has been a change in user auth by a different client instance. This may be expensive

  2. we direct people to only init a single supabase client if they're using auth

  3. we make createClient return a singleton

any other?

@phamhieu
Copy link
Member

phamhieu commented Aug 18, 2020

@awalias what you describe seems to be another issue related to front-end.

The original error reported by @thorwebdev is from gotrue logout api. It can be reproduced easily.

  1. start your test supabase project, run slack clone quick start to create required tables
  2. pull slack clone app, update env with your test project keys and run it
  3. login and logout multiple times slack-clone client (with the same acc and client) you can see the error

Screenshot 2020-08-18 at 1 54 51 PM

I already check logout api on gotrue. The last commit on logout.go breaks the check mechanism.

Before
it works properly, because the claim is retrieved before clearing token
https://github.com/netlify/gotrue/blob/47cc9ce137a24c96985ee3e742b0f0adfb6f146c/api/logout.go
Screenshot 2020-08-18 at 2 02 43 PM

After
https://github.com/netlify/gotrue/blob/8304885327eb93a7346f4b27658f470499c39107/api/logout.go
Screenshot 2020-08-18 at 2 04 32 PM

@awalias
Copy link
Member

awalias commented Aug 18, 2020

I think the response from gotrue is actually correct in this instance, if you look at the request headers on the slack clone app, you will see that the apikey and auth bearer headers are the same, in this case the jwt being (mistakenly) sent is the anon key:

image
image

for comparison here is an example of a successful logout, with decoded jwt below:
image
image

The bug seems to be that the supabase-js client calling logout does not have the current user token, since it was already cleared from the client by the other instance

the "double logout" seems to be coming from here: https://github.com/supabase/supabase/blob/fed822f48c5e441eb867fa756443e362ac47423f/examples/slack-clone/components/Layout.js#L59

and here: https://github.com/supabase/supabase/blob/fed822f48c5e441eb867fa756443e362ac47423f/examples/slack-clone/pages/channels/%5Bid%5D.js#L16

@awalias
Copy link
Member

awalias commented Aug 18, 2020

also as a side note - we actually don't make use of the cookies set by go-true, we manage these ourselves using local storage inside supabase-js

@phamhieu
Copy link
Member

phamhieu commented Aug 18, 2020

Thanks @awalias for clarification. After modifying slack clone example to use a single Supabase client, everything works properly.

@phamhieu
Copy link
Member

phamhieu commented Aug 18, 2020

Currently, supabase-js persists accessToken, refreshToken and currentUser to localstorage while also keeps them as class params inside supabase.auth. When we have multi supabase clients, these params can be out of sync.

We should use localstorage as the source of true and don't keep them as class params. It's the same as how we get authHeader to supply PostgrestClient. What do you think? @kiwicopple

@awalias
Copy link
Member

awalias commented Aug 18, 2020

  1. is it inefficient to fetch from local storage every time?
  2. what about server-side / node

maybe keep track of them internally but always check local storage first (if it exists?)

@phamhieu
Copy link
Member

  1. right now everytime you call a request with postgrest client, it will read localstorage for accessToken to include in the header. It works ok until now. So i think it's efficient enough.
    Screenshot 2020-08-18 at 6 37 24 PM
  2. for server-side, accessToken should included in the header. To get refreshToken and currentUser we can call gotrue /user endpoint with accessToken

kiwicopple added a commit that referenced this issue Nov 2, 2020

- Fixes #32 Major DX change: response and error handling
- Fixes #49 When no `supabaseKey` is passed in it throws an error
- Fixes #31 chore: set up semantic releases
- Fixes #15 `supabase.auth.logout()` throws "Invalid user" error.
- Fixes #20 Auth: Change DX of user management
- Fixes #30 Supabase auth interface missing informiation
- Fixes supabase/supabase#147 supabase/supabase#147
- Partial fix for supabase/realtime-js#53  - if there is no token provided. The error needs to be caught at a socket level.
- Adds magic links


## BREAKING CHANGES

- See all breaking changes in RELEASE.md v1.0.0
- Errors are now returned and not thrown
- Auth now uses `@supabase/gotrue-js` interface
- `supabase.getSubscriptions()` only returns open subscriptions



* Updates the config

* chore: Migrates the basic outline to TS

* Adds a simple example showing how it can be used.

* chore: Moves tests to jest

* chore: Adds semantic releases

* Moves the subscription into it's own class

* Updates the todo readme with simple instructions

* Updates installs

* Revverts commented code - sorry for the spam

* docs: adds JSDoc to some functions

* chore: Adds a function for backwards compat

* chore: migrates the client to SupabaseClient

* This change attempts to make the naming conventions the same as Thor's previously

* Updates GoTrue to latest version

* Adds generic type to the from, and updates the name of the query builder

* Updates to latest versions of all packages

* Updates the example to make sure it's working

* Refactor SupabaseQueryBuilder

* Adds prettier hook

* Add TypeScript next.js example.

* Declutter SupabaseClient and make work with gotrue-js changes.

* Bumps the GoTrue version

* Bumps postgrest to include the types

* Temporarily adds the spec so that I can use it in our docs

* Update examples and add resetPassword.

* Bump gotrue-js version.

* Update lockfile.

* Add auth magic link capabilities.

* Gotrue-js user and session method updates.

* chore: Adds release notes

Co-authored-by: Thorsten Schaeff <[email protected]>
Co-authored-by: Thor 雷神 Schaeff <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants