Sharing sessionStorage between tabs (Javascript)



When managing credentials we also need to think about it’s security. We now have a localStorage and sessionStorage to manage the credentials on our website. So, which and how can we use both of then?

Differences

First we need to know the differences between each of then.

sessionStorage: The first thing we need to know about session storage, it’s implicit on its own name, sessionStorage keeps the values only on the same session. So, if we close the current tab that the session is saved, we loose their value.

localStorage: Different from sessionStorage the localStorage keep the value until the user cleans it (Can you see the problem here?).



Why to not use always localStorage?

LocalStorage is easier to maintain and we will not have a lot of problems using it. But the problem here is: Imagine the situation when an Admin is logged in any computer that is not his own and wants to close his session, if we are using the sessionStorage, once he closes the opened tab, the session will be automatically destroyed, but when using the localStorage, if any other person open the website it ill be using the opened session.

Knowing that, we need to keep those credentials safe.

That is why we use sessionStorage, but the sessionStorage is saved only in the same tab, that indicates that each time any user wants to open a new tab he will need to login again? NO!!! That is the purpose of this article. You can use the sessionStorage without needing to validate the new tabs and we you close all of then, you are automatically logged out form the website!

How does it works?

First we need to imagine some situations:

  1. The user opens the website for the first time
  2. The user logged in opens a new tab
  3. The user without credentials tries to access the protected page
  4. The user wants to sign out

For each situation we need to catch and take some actions.

Let’s go step by step…

Theoretical foundation

When any tab call a localStorage event, It will be visible by any open tab and we cant take advantage of it.

If we know that dispatching a localStorage all tabs will see it, we can use it to notify then that a new tab have been opened.

We just need to create a listener on the protected page (if you are using react it could be a HOC) to listen all storage events.

Now we just need to check for the 4 situations we talked earlier, and do what we need to do!

Implementation

Here we can see an code example using ReactJS

class HOC extends React.Component {
  constructor(props){
    super(props)
    window.addEventListener('storage', () => {})
  }
}

Now we have a component that will listen to all storage events, now we just need to make a request when opening the page. To do that, we need to dispatch a storage event with some random data and a key.

componentDidMount() {
  window.localStorage.setItem('REQUESTING_SHARED_CREDENTIALS', Date.now().toString())
  window.localStorage.removeItem('REQUESTING_SHARED_CREDENTIALS')
}

As you can see, we are deleting the created storage at the same moment that we are crating. We just need to let all the other tabs know that we opened a new one.

We are also using a key that indicates that we are requesting for the credentials, we can also add this event on our listener.

window.addEventListener('storage', (event) => {
  if(event.key === 'REQUESTING_SHARED_CREDENTIALS')
    console.log('Its working')
})

Now we already have and listener that will listen to the credential request and will take some action. But… we need to check if the user is logged in right? Otherwise we have no credentials to share. So, let’s change our listener a little bit.

window.addEventListener('storage', (event) => {
  const credentials = window.sessionStorage.getItem('CREDENTIALS_TOKEN')
  if(event.key === 'REQUESTING_SHARED_CREDENTIALS' && credentials)
    console.log('Its working')
})

Oh now we know if the user is logged in when the new tab requests the credentials!

But… We need to listen when the tab with credentials sends it right?

To do this we need to wait for another key on the listener and we need to set the opened tab to send those credentials with the event key. And now our listener will be like this:

window.addEventListener('storage', (event) => {
  const credentials = JSON.parse(window.sessionStorage.getItem('CREDENTIALS_TOKEN'))
  if(event.key === 'REQUESTING_SHARED_CREDENTIALS' && credentials) {
    window.localStorage.setItem('CREDENTIALS_SHARING', JSON.stringify({ token: 'any-token-you-want' }))
    window.localStorage.removeItem('CREDENTIALS_SHARING')
  }
  if(event.key === 'CREDENTIALS_SHARING' && !credentials){
    window.sessionStorage.setItem('CREDENTIALS_TOKEN', event.newValue)
  }
})

Now everything is almost done. We are already requesting for the token and sending it from any logged in tab. Now we need to create a function to logout in all the tabs at once and check if there is no logged tab.

The last one is easy, we can do it setting a timeout function in about 2 seconds to verify if the tab already have a credential.

To logout all the tabs we need to add the following clausure to our listener

if(event.key === 'CREDENTIALS_FLUSH' && credentials){
  window.sessionStorage.removeItem('CREDENTIALS_TOKEN')
}

And create a button that will dispatch this event

onLogout = () => {
  window.localStorage.setItem('CREDENTIALS_FLUSH', Date.now().toString())
  window.localStorage.removeItem('CREDENTIALS_FLUSH')
}

And then..

<button onClick​={() => this.onLogout()}>Sign out</button>

That’s it!!!

To view or add a comment, sign in

More articles by Marcio Mariani

  • Flutter dependency injection + get

    Hi devs, I don't know if you are aware but recently a Brazilian guy released a new flutter package to simplify our…

  • Dropdown selection easy as pie

    Hi Dev! Recently I was building my UI for MEL (an app that I will be launching in a near future), and faced a problem:…

  • Let's talk about Unit Test (Flutter)

    Are you ready?? What is Unit Test and what's it importance? Well, we have a common practice among developers, to write…

  • Flutter sign with firebase

    Flutter is a framework created by Google, to develop native applications for web, mobile and desktop using a simple…

Others also viewed

Explore content categories