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

client.resetStore on logout is wrong #2774

Closed
stevensacks opened this issue Dec 25, 2017 · 12 comments
Closed

client.resetStore on logout is wrong #2774

stevensacks opened this issue Dec 25, 2017 · 12 comments
Assignees

Comments

@stevensacks
Copy link

https://github.com/apollographql/apollo-client/blob/master/docs/source/recipes/authentication.md#reset-store-on-logout

The documentation says that you should use client.resetStore() on logout, but that is wrong. If you do that, then the queries get refetched and cached with User A's permissions and then when User B logs in, the query is already fetched and cached, so it doesn't fetch data again, and instead it shows User A's data to User B because it's in the cache.

Either a new function called clearStore() needs to be created or the documentation should be updated to say that localStorage.clear() (or whatever methodology you're using to persist data locally's clear out function).

@fenos
Copy link

fenos commented Jan 2, 2018

to me the doc sounds correct. What about using this flow so that you'll always get consistent cache for your logged in / out users?

  • Guest navigate website => Filling the cache with guest queries
  • Login User A => client.resetStore() fresh cache for this User A.
  • User navigate website => Filling cache with User A.
  • Logout User A => client.resetStore()

Then if the flow repeats for User B then you'll always have a fresh cache for your users / guests that doesn't collide.

From what I'm aware Apollo 2 doesn't persist the cache when using InMemoryCache it keeps it in memory 😄 at any page refresh will get lost and re-filled as you land on the pages.

@blacklakeDev
Copy link

@fenos tried your method didn't work.

Seeing the same problem here.

Intended:
errors resulting from UserA's queries should be cleared out on client.resetStore()

Actual:
User B component props show errors from userA's queries

Query from User A returns an error in data, as expected.
{ error: { graphQLErrors: [ { Error: <message from User A>} ] } }
However, after client.resetStore, User B still sees:
{ error: { graphQLErrors: [ { Error: <message from User A>} ] } }
I dug in deeper and saw that the errorLink from UserB didn't return any error, so the Error must have been read from cache. Then I console.log the cache from before and after resetStore and found that store data was cleared. Makes no sense. Anyone else has a clue?

@blacklakeDev
Copy link

here are the versions

apollo-client-preset@1.0.3
apollo-client@2.0.3
apollo-cache-inmemory@1.1.1

@n1ru4l
Copy link
Contributor

n1ru4l commented Jan 9, 2018

@fenos Did you test what you are writing?

For me resetStore also resulted in showing data from the previous user. In a web app you could do a page refresh.. But not in a react-native app 😅

I worked around this by using writeQuery to overwrite the existing data with null. However this is not optimal.

~~@blacklakeDev I have not updated to apollo-client 2 yet. The Cache has a reset method. Maybe this could be the clearStore implementation we both need~~~ Edit: apollo-client does that for us!

Edit: Not related to your actual issue.

@n1ru4l
Copy link
Contributor

n1ru4l commented Jan 9, 2018

@blacklakeDev I created this example: https://codesandbox.io/s/61o2xxmn0w

It seems to work. Could you modify it so that it reproduces your issue? Could it be possible that your query is inactive (not consumed by any component) at the time when resetStore is called?

Edit:

I was able to reproduced this issue in the sandbox!

You should change the issue title since it is misleading.

Edit:

This issue could be related to #2513

@bogdansoare
Copy link

also having this issue.
Agree that we need a clearStore() function, because after logout (removing the auth token) and calling client.resetStore() the refetched queries throw errors because the lack of authorization

@wmertens
Copy link
Contributor

wmertens commented Mar 2, 2018

If you have active queries that require authorization after logout, that just means you need to redirect the user to a page without privileged queries before logout. The queries are just doing what they are supposed to do.

What you can do, however, is intercept queries that result in a permission error, and if the user is logged out, prompt them to log in again. That way you can have an SPA that is running longer than the session time, and the user can log in again without losing app state.

@Stradivario
Copy link

Stradivario commented Mar 19, 2018

Also what about subscription ? When you do resetStore it doesn't destroy Websocket connection instead i should do something like

this.webSocketLink['subscriptionClient'].close();

I have created some logout logic like so

    resetStore(): Promise<ApolloQueryResult<any>[]> {
        this.webSocketLink['subscriptionClient'].close();
        return this.apollo.getClient().resetStore();
    }

I have also created apollo graphql client for angular especially for Gapi (Server Side Easy Api based on Apollo) but can be used in other Graphql Servers check this out
https://github.com/Stradivario/gapi-angular-client

@hwillson hwillson self-assigned this Sep 5, 2018
hwillson added a commit that referenced this issue Sep 5, 2018
A new `clearStore` method has been added, that will remove all
data from the store. Unlike `resetStore`, it will not refetch
active queries after removing store data.

Fixes #2411.
Fixes #2774.
Fixes #3539.
Fixes #3813.
hwillson added a commit that referenced this issue Sep 5, 2018
* Add `clearStore` method

A new `clearStore` method has been added, that will remove all
data from the store. Unlike `resetStore`, it will not refetch
active queries after removing store data.

Fixes #2411.
Fixes #2774.
Fixes #3539.
Fixes #3813.

* Changelog update

* Add `clearStore` to API docs

* Add `clearStore` reference to authentication docs

* Add `clearStore` reference to caching docs
@hwillson
Copy link
Member

hwillson commented Sep 5, 2018

#3885 adds a new client.clearStore() method to the public API, that will clear the store without refetching active queries. Thanks!

@raymclee
Copy link

raymclee commented Sep 6, 2018

how to use the new clearStore function?

@n1ru4l
Copy link
Contributor

n1ru4l commented Sep 7, 2018

@cheuk3 Should be available once the next apollo-client release is published.

@gentlee
Copy link

gentlee commented May 12, 2020

Does client.cache.reset() do the job right now?

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants