Best strategy for OAuth2.0 across browsers and across tabs within the same browser

active-directorycross-browserlocal-storageoauth2

I have developed a login system using OAuth2.0 that is currently working within one tab in one browser. Without diving into the code, the system works by having the user enter their credentials to login, the credentials are sent up to the API (WebAPI2 .Net) from the client (Angular), the user is logged in via Active Directory, and then an access token and refresh token are returned to the client.

I am currently storing these within cookies. When an access token expires, the refresh token is grabbed from the cookie and used to get a new access token. All of this is working within one browser tab. However, we want to allow the user to be logged in to multiple tabs within a browser, and/or multiple browsers at the same time without effecting eachother (like facebook, etc.) Cookies are the wrong solution for storing these tokens because they don't communicate between different tabs, so I did some research and found localStorage which probably solves the between tabs problem.

However, I wanted to get some opinions on best strategy for being logged in across multiple tabs/browsers with the same login using OAuth2. I don't think you can store the tokens in SQL because then the call to the API isn't secure to get the refresh tokens across browsers. Do you create separate tokens in each browser with the same login and then localStorage in each browser to share that browser's token? Or is there a way to share refresh tokens safely across multiple browsers?

Best Answer

Between tabs, use defineProperty and sessionStorage:

Object.defineProperty(sessionStorage, "setItem", { writable: true });
sessionStorage.setItem = function () { /* Login logic */ };

Between browsers, use window.postMessage to communicate the need redirect to the authorization page:

 // If the current window is the 'parent', change the URL by setting location.href
  if (window.top == window.self) {
    window.top.location.href = "/auth/shopify?shop=myshopname";

  // If the current window is the 'child', change the parent's URL with postMessage
  } else {
    message = JSON.stringify({
      message: "Shopify.API.remoteRedirect",
      data: { location: window.location.origin + "/auth/shopify?shop=myshopname" }
    });
    window.parent.postMessage(message, "https://myshopname.myshopify.com");
  }

References

Related Topic