Toggle/switch between accounts easily

Some of you might be familiar with Instagram’s ability to easily switch between accounts (for example, if you have a personal account and a business account).

I’ve got users on my site who might want to do the same. Any thoughts on how to accomplish this? Can’t find anything in the accounts documentation. Essentially it would need to remember your accounts and allow you to easily switch between them. Will update this thread if I figure anything out, but thought I’d ask if anyone else had tried to solve a similar problem.

Accounts package does not implement such behavior.

It has to be said, that while such behavior may be implemented in many ways, Instagram seems to use quite simple approach, so that multiple accounts data is stored in memory at the same time.

Its important to keep in mind, for user - account is nothing more than visual data related to it such as name or avatar. While server(in this case) is only concerned about cookies, assigned once you authenticate and sent with every response.

Sadly, I’ve only returned to Meteor a day ago, so I won’t anticipate much on implementation best for meteor.
Nor like I actually have instagram account to verify :smiley:

But here’s how their cient-side store, related to account looks like. Good luck!

1 Like

One approach would be to store login tokens yourself in localStorage, and then use Meteor.loginWithToken to switch accounts. If the token expires, you can pull up a “please verify your password” screen.

Some data that you might want to store:

  • user id
  • user email / username / authentication type
  • login token
  • token status
  • etc

You could also write Meteor methods to fetch the user document through the login token, to display, for example, how many notifications each user has.

2 Likes

@msavin that’s an interesting idea! How do I access those tokens? I see an array at Meteor.user().services.resume – each one has “when” and “hashedToken”. But trying Meteor.loginWithToken() with either one of those arrays or the hashedToken doesn’t seem to accomplish much!

Edit: Accounts._storedLoginToken() returns a token, but passing that to Meteor.loginWithToken doesn’t seem to work. This appears to because the token changes every time I log in.

Edit 2: Okay, I was headed in the right direction. As long as they don’t log out (and just switch accounts instead), it works fine. Here’s the code that put me in the right direction: Error logging in with token in two separate applications

Edit 3: Okay, once you’ve got two active tokens (logging out nullifies them), switching between them is a piece of cake. I’d obviously want to save a bit of nice information (avatar, username) so that I can show a nice, easy-to-click toggle in the UI. The last hurdle before I do that is to allow a user to log in with a second account (“add an account”) using the accounts-ui package (which, once logged in, shows a “Log out” view). Hopefully I can programmatically get that to switch back to a login prompt. Otherwise will have to manually code something that uses the Accounts.loginWithPassword, Accounts.loginWithFacebook etc.

1 Like

Yep that sounds right. You could make a nice package out of this.

Just an update here: a bit challenge was being able to “log out” a user without resetting their token. The default logout behavior always resets it, but with a bit of digging I found that Accounts.makeClientLoggedOut() logs the client out, but keeps the token alive. This also allows you to reset the login form of accounts-ui, which means that a second user can be connected – thus allowing you to store multiple “active” login tokens that can be toggled between with Meteor.loginWithToken(token).

All that’s left at that point is working out the UI/UX of it (ie, saving a profile picture and username to session storage, presenting it in a pretty format, and triggering Meteor.loginWithToken(token) when the user clicks it).

Hope that helps anyone who is looking to implement something similar!

1 Like

Hi @jasongriskoff, Nice work here, I think I’ll use something along these lines for allowing a user to quickly between accounts.

It seems I have to do one more step though - reloading the page after Accounts.makeClientLoggedOut()

Typing this into the client console doesn’t work:

token = Accounts._storedLoginToken()
Accounts.makeClientLoggedOut()  // logged out and taken to log in screen
Meteor.loginWithToken(token) // nothing happens

However, this does work:

localStorage.setItem('storedToken', Accounts._storedLoginToken())
Accounts.makeClientLoggedOut()  // logged out and taken to log in screen
location.reload()
Meteor.loginWithToken(localStorage.getItem('storedToken'))

Did you mange to get it to work without the reload step?

Hi @wildhart, I don’t have to reload the page for it to work, but I do save the token in a similar manner to what you’ve shown in your second example. I’m guessing that doesn’t work without the reload, even tho you’ve stored the token?

Yeah, without the reload it won’t let anyone else log in. Weird.

The only difference I can see between a Accounts.makeClientLoggedOut() and Meteor.logout() (which lets a new user log in) is that with the former, minimongo is left with an orphan document in the users collection:

image

With Meteor.logout() the users collection is empty, all that’s left is the meteor_autoupdate_cilentVersions document.

Looking through the DDP logs I can’t find any subscription which aren’t unsubscribed. I removed autopublish long ago.

I am using the excellent meteor-partitioner by @mizzao to divide my database among different client groups which is where the user.group field is coming from. I need to dig through its code to see if that could be leaving something behind…