2023-01-13 - Frontend Authentication Ideas

From Izara Wiki
Jump to navigation Jump to search

Frontend Authentication

Storing tokens in Frontend

There are conflicting opinions where authentication tokens should be stored in frontend applications, some push for session and some in local storage.

Old method

  • Tried to avoid storing anywhere in browser managed locations (local/session storage) by storing in each application instance's logic, ie React objects
  • When a new tab opened it would use local storage to request tokens from any other tabs that had them, the response would copy into local storage then immediately remove them, so the calling tab would receive the message with the tokens but the tokens would not remain

Problems

  • When all tabs for the app are closed, the tokens are lost
  • Will not retain login when browser or all tabs for the app are closed
  • The app would appear to retain login if reopened with Cognito's cookie timeout (1 hour) because browser remembers Cognito's cookie so when redirected to Cognito, Cognito would return as if the user had signed in again

Solution

  • If we want the browser to remember a user's sign in after closing the browser, we must store the tokens somewhere persistent
  • Local storage and Cookies persist, cookies are insecure so Local Storage should be used
  • Sacrifice the possible protection of not storing tokens in local storage all the time, but the old method still used local storage to pass tokens between tabs so it was risk reduction rather than eliminating the risk

Storing login details between browser closure

  • Want to remember sign in status after browser has been closed for up to the length of the refresh token expiry (normally 30 days)
  • Do this by storing the tokens in Local Storage
  • There are other details we request from backend when a user signs in such as style, language, username
  • Style and language we do not remove from local storage after sign out, so they persist after a user signs out and should persist until changed, either manually on the site or by signing in and received the new sign in details that might be different to that stored in local storage
  • User name and other user details are removed when sign out because we show this when signed in (with user name)
  • Decision whether to show signed in menu or not can come from whether the username is stored or not, rather than from whether tokens are stored or not
  • Considering storing these user details into local storage as well so when browser reopens it does not need to request these from backend

When and Where to check tokens

  • planning on doing this on a per component level, any component that requires sign in checks the tokens and redirects to sign in page if not have/refresh expired
  • Can think of two types of components

Component that requests data that requires sign in

  • planning on checking have token and not expired in BackendRequest, this way right before requesting data from backend we check is signed
  • BackendRequest is only used for authenticated requests to backend, if we have un-authenticated requests to backend will need another library
  • the BackendRequest is normally called in the empty filter useEffect, which is initiated when the component mounts for the first time
  • if multiple components in a route require sign in on mount, the first should redirect to sign in page
  • if user stays on route for a long time, eg changing data, sign in might expire during that time, but I think it is OK because any new request to BackendRequest, such as submitting a form or re-loading the data will trigger a new sign in check

Component with input that requires sign in on submission

  • in this case no data is requested from backend on mounting the component, but it would be uncomfortable for the user to sign in after completing the form (when the BackendRequest is sent)
  • this could be handled on a case by case basis, with an independent sign in check when the component mounts
  • additional sign in checks could be added, eg whenever the component renders, if we wanted to catch expired sign in before submission to backend