title: How to redirect to correct client route after social auth with Passport (react, react-router, express, passport)
body: <p>I have a React/Redux/React Router front end, Node/Express back end. I’m using Passport (various strategies including Facebook, Google and Github) for authentication.</p>
  
  <p><strong>What I want to happen:</strong></p>
  
  <ol>
  <li><p>Unauthenticated user attempts to access protected client route
  (something like <code>/posts/:postid</code>, and is redirected to <code>/login</code>.
  (React Router is handling this part)</p></li>
  <li><p>User clicks the ‘Log in with Facebook’ button (or other Social auth service)</p></li>
  <li>After authentication, user is automatically redirected back to the route they were attempting to access in step 1.</li>
  </ol>
  
  <p><strong>What is happening instead:</strong></p>
  
  <p>The only way I’ve found to successfully handle Passport social authentication with a React front end is to wrap the ‘Log in with Facebook’ button in an <code>&lt;a&gt;</code> tag:</p>
  
  <p><code>&lt;a href="http://localhost:8080/auth/facebook"&gt;Facebook Login&lt;/a&gt;</code></p>
  
  <p>If I try to do it as an API call instead of a link I always get an error message (this issue is explained in a lot more detail here: <a href="https://stackoverflow.com/questions/44814735/authentication-with-passport-facebook-express-create-react-app-react-rou">Authentication with Passport + Facebook + Express + create-react-app + React-Router + proxy</a>)</p>
  
  <p>So the user clicks the link, which hits the Express API, successfully authenticates with Passport, and then Passport redirects to the callback route (<code>http://localhost:8080/auth/facebook/callback</code>). </p>
  
  <p>In the callback function I need to (1) return the user object and token to the client, and (2) redirect to a client route — either the protected route they were trying to access before they got redirected to <code>/login</code>, or some default route like <code>/</code> or <code>/dashboard</code>.</p>
  
  <p>But since there isn’t a way to do both of these things in Express (I can’t <code>res.send</code> AND <code>res.redirect</code>, I have to choose one), I’ve been handling it in what feels like kind of a clunky way:
  <code>
  res.redirect(`${CLIENT_URL}/user/${userId}`)
  </code></p>
  
  <p>This loads the <code>/user</code> route on the client, and then I’m pulling the userId out of the route params, saving it to Redux, then making ANOTHER call to the server to return the token to save token to localStorage.</p>
  
  <p>This is all working, although it feels clunky, but I can’t figure out <strong>how to redirect to the protected route the user was trying to access before being prompted to log in.</strong></p>
  
  <p>I first tried saving the attempted route to Redux when the user tries to access it, thinking I could use that to redirect once they land on the profile page after authentication. But since the Passport auth flow takes the user off-site for 3d-party authentication and then reloads the SPA on <code>res.redirect</code>, the store is destroyed and the redirect path is lost.</p>
  
  <p>What I ended up settling on is saving the attempted route to localStorage, checking to see if there is a <code>redirectUrl</code> key in localStorage when the <code>/user</code> component mounts on the front end, redirecting with <code>this.props.history.push(redirectUrl)</code> and then clearing the <code>redirectUrl</code> key from localStorage. This seems like a really dirty workaround and there has got to be a better way to do this. Has anybody else figuree out how to make this work?</p>