4

I'm trying to implement social login functionality in a MERN SPA so that users can login to my site using their Google/Facebook/Twitter/etc. login. This is clearly a very common scenario, and there are tons of posts and examples that address how to accomplish this using various authentication flows (i.e. authorization code flow, authorization code flow with PKCE, etc.)

However, for the flow I am trying to implement (described below), I cannot get my head around how to handle the redirect back from the identity provider without causing the user agent to refresh and lose state.

For example, here is the flow I am trying to implement for logging in with Google:

  1. User clicks "Login with Google" button, which directs user agent to Google's authorization endpoint.

  2. Google authenticates user and redirects them back to my redirect URI with an authorization code.

  3. User agent makes API call to backend of my site providing the authorization code.

  4. Backend of my site sends authorization code to Google's token endpoint (along with my app's client_id and client_secret), gets back ID token, creates suitable JWT, and returns that JWT back to user agent.

  5. User agent stores JWT and sends it as bearer token in all subsequent calls back to server.

The problem I have is at step 2. Since this step causes the browser to reload my SPA, the state in the React components gets cleared. I can partially get around this using localStorage, but that adds complexity.

Is it possible to implement this flow without the browser having to reload my app and clearing component state? Or, is there some other approach I should be using that gets around this apparent pitfall?

(I am new to React/SPAs and OIDC, so please excuse any glaring misconceptions or oversights.)

crosen9999
  • 823
  • 7
  • 13

1 Answers1

1

An SPA will reload its index.html and therefore restart the app after any of these actions, and you cannot prevent that:

  • Initial Page load
  • OIDC response is received
  • User reloads page, eg via cmd+R or F5
  • User opens a new browser tab within the app
  • Logout response is received

The usual technique is for the SPA to store state before issuing the OIDC redirect, including its current location, eg /products/2. Then, on every page load, check whether the current URL represents an OIDC response (eg contains code and state query parameters). If so then perform step 3 from your flow, then restore from the app's stored state.

If it helps, here is some React code of mine that does this type of thing, by storing the current location in session storage.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
  • Hey, Gary. The Link you provided is not working. can you provide an updated link? I'd like to see how you handle it in react, actually, since i'm facing the same scenario. – TomerBu Jun 19 '23 at 07:47