Is Application.reset() the recommended way to clear caches of private data on logout?


#1

Hello, I’m working on an Ember-based site, and I’ve just been trying to fix a bug in which a newly logged in user can see the last logged in user’s data. The problem was that I wasn’t clearing the previous user’s data on logout. My research and exploration seem to indicate that Ember provides only one way to do this: Application.reset(); and that it is intended by the Ember developers that I use that method in this case, though reset() may actually be primarily designed for use in automated testing or some such. Is all that correct?

I’ve gone ahead and tried to use Application.reset() to clear user data. It didn’t work well.

(Actually, before trying that, I tried simply clearing the Ember Data store via a small hack; I think my hack did correctly clear the store, but then I still had problems, because some controllers or views or who knows what were still holding onto some computed properties’ values that included the logged out user’s data. So Application.reset() seemed the only way to go.)

The problem was that I actually need some things to be remembered across the cache-clearing operation. For instance, if my site’s server logs the user out for some reason but the browser doesn’t know it yet, then when the user tries to hit a login-protected page, they’ll be redirected to the login page and shown a message to the effect of “You’ve been logged out [for reason X]; please log in again.” On logout, I want to clear all private data, yes–but I want to remember (in the LoginController) that the special message is to be shown.

Another example: This site supports multiple OpenIDs per user account, and a user may register a new one anytime. Registering a new OpenID for an old account involves logging in with the new ID to a new, temporary identity, logging out (but remembering some things about the ID), and then logging into the old account and associating the new ID with it. So, here is another logout that’s supposed to leave the JavaScript remembering something about the user. It turns out to be awkward and weirdly complex to try to decide in my code whether a reset is needed or not, during these loggings in and loggings out; and I do want to know whether one is needed, because resetting at the wrong time will cost me that important memory of the ID and wreck a feature of the site. Maybe I should have written things differently, so this stuff is less awkward. But I think it’s not Ember’s job to enforce that. And the code as I wrote it worked perfectly well until I started trying to reset things; and if I could just say WHICH caches I wanted reset, then none of this awkwardness would ever have arisen at all.

These are small problems, and there are probably a number of simple, decent ways to solve them that work with Application.reset(). For instance, maybe I could pass parameters across login/logout via sessionStorage, cookies, or URL parameters. But I tentatively claim that I shouldn’t have to rewrite my previously working features just because I didn’t know from the start that you’re supposed to be ready to forget EVERYTHING as soon as a user (explicitly or implicitly) logs out. My problem would be much easier to solve if I could simply tell Ember to clear “everything except what’s in controllers X, Y, and Z” or some such. Is there a fundamental reason why Ember shouldn’t include a feature that’d make something like that easy? Is it just something that the developers haven’t gotten around to implementing? Or… is there something like that already that I just haven’t found?

I learn from https://github.com/emberjs/data/issues/235 that, as of most of a year ago, you just weren’t supposed to be able to pass things around among controllers across logout events, if you wanted to clear your data on logout. Assuming I’m interpreting things correctly. And I don’t seem to be finding any update to that conversation.

Anyway, that seems rather silly. It’s perfectly reasonable for a website to want to know and remember at least a few little things about a user who isn’t logged in, as in the cases I’ve encountered. Couldn’t there be any number of such cases? Surely a mandate that the entire world must end and then begin again on logout is not really part of the core Ember philosophy? Or… is this something that JavaScript in browsers, in general, makes difficult? Maybe there really is no way to clear all the private stuff for sure, unless you do nuke everything? But in that case, presumably not even Application.reset() would be enough.

(As a side issue–although I did work around the problems I was having with the loss of the parameters I was passing, I still ultimately couldn’t use Application.reset(), because no matter where I tried calling it, it seemed to break things and cause arcane exceptions. If use of this method on logout is intended, then more documentation on that usage would be helpful. As it is, I’ve resorted to simply refreshing the page, which is much much easier.)


#2

It’s disappointing no one replied to this, because I’ve been trying to improve the time it takes to handle logging a user out and App.reset() often takes 10s+. If you gained any insights since posting, let me know.


#3

We chose to do a hard reset (full page reload) to be sure everything is properly cleared (quickly). Anything that (may) need to persist across sessions, we preload on app boot using store.push or the ENV object (ember-cli).


#4

the problem with a hard reset, is that it is incompatible with things like cordova.


#5

I’m actually asking this in the context of improving a phonegap app, hard reset is in fact possible, just not via a normally used location reset.

window.location.href = window.location.toString().substr(0, window.location.toString().indexOf('#'));

However, I found that too could lag a while. Currently, I’m carefully resetting my login & session controller, session store, and clearing ember-data records.

I’d rather not have controller properties hanging around, but the speed gained by resetting this way so far seems to be worth the price of leaving some controllers in altered state in our case (outside of our login/session controllers, nearly all our controllers reset their own state on willTransition for various reasons anyway, and due to the nature of our data, most the computed properties are on the models that get wiped with the store).


#6

No experience with either so this is a shot in the dark but could the following be an option?

  • Subclass application
  • Override the reset function
  • Store the stuff you’d like to persist explicitily at the start of the new reset
  • Clear the store
  • Call this._super() (maybe even wrap this in a run.later to allow the system some time for itself)
  • Restore the stuff you’ve saved before
  • Display a fancy loader before calling app.reset.

I’d personally prefer something to lag for a while but have some sort of certainty about the app state then having something really fast where I’m not 100% sure what the state looks like. But it depends on the lag I guess.


#7

So i took a look at application.reset, and its quite a big reset. i know in my use case i only need to clear the data, so i clear the store and then redirect to the login page, i have seen a bug of the navigation bar not changing, and takes like 1-2s on average.

so I suppose ask yourself do you need to do all of this.

Reset the application. This is typically used only in tests. It cleans up the application in the following order:

Deactivate existing routes Destroy all objects in the container Create a new application container Re-route to the existing url


#8

That was why I started discussing this actually, because App.reset() does far more than is needed to clear out a user.

The main worry most have had is that computed properties / controller properties don’t get reset otherwise, and calling controller.reset() appears to be broken in Ember 1.7.0.

This could represent a security hole if a sensitive value is hanging around in a controller someplace for the next user to stumble upon, and at a minimum it can become an annoying user experience if the app isn’t returned to a normal default state.

In a normal web scenario this is a non issue as soon as the tab is closed, but in a phonegap scenario where multiple users share the same device (e.g. sales reps using shared iPads from the sales floor) this becomes relevant. Incidentally, this use case is also why a fast logout is needed in our case.

Thus far, the speed concern has outweighed the concern of controller properties hanging around, and we’ve manually reset the properties on any controllers that are considered sensitive.


#9

ye seems thats the best way to do it


#10

I’m weighing this same question after running into trouble with refreshing the page after logout on a Phonegap app. I figured out how to do it consistently across platforms (similar to @jthoburn’s suggestion above), but it left me wondering if there’s a better way. Is there anything that gets left hanging around after App.reset()? Or is the only reliable way to clear all data with a page refresh?


#11

I have same issue.

App.reset() does not seem to clear controller properties bound to component properties. I don’t know if it’s intended or not, but this jsbin demonstrates it. I would suggest override App.reset() to also explicitly get all controllers and reset their bound properties.