Home » Nodejs » Passport.js + Express.js forward user to original destination after authenticating

Passport.js + Express.js forward user to original destination after authenticating

Posted by: admin December 5, 2017 Leave a comment

Questions:

I have an app that is Node + Express + Passport on the server and jQuery + Backbone.js on the client. The client makes use of hash tags in the URL, but for some functionality it’s important for the user to be logged in.

I’d like the app to be accessible via URL, e.g. http://mydomain.com/app#cone/waffle/flavor/mint/toppings/sprinkles such that:

  • if user is already logged in, they go to the requested URL directly without hassles
  • if user is not already logged in, they go to /login and then go to the requested URL

Following this SO post,
Custom returnUrl on Node.js Passport's Google strategy, I have it so that

  • If they are logged in already, they go directly the URL, hash tags and all
  • If they weren’t logged, it takes them to the login page, then to the requested url, but…

It seems to strip out the hash parameters from the original URL on the redirect after login.

Is there any way to preserve the hash parameters when redirecting them to the original destination?

From this post, Getting hash parameters from request url I get the idea that the hash tags aren’t available on the server, which is the whole point of using hash tags.

So I suspect it’s not possible. Maybe cache the params locally somehow and retrieve them on redirect, say to [original URL minus hastags] + #use-cached-params?

Answers:

Hash parameters are browser-only, they won’t go to the server. You can use this technique though for redirecting back, hash-tags and all:

  • GET /some/page#with/hash
  • logged in? then render the page
  • not logged in? render a page that has some JavaScript on it, say ‘getHash.jade’
  • getHash.jade: copies the full URL, then redirects to ‘/login&redirect=’ + originalURL
  • GET /login (now you can save the hash on the server and take it from there)
Questions:
Answers:

Here is how to capture anchor links in a bit more detail. Works across all web frameworks.

I’ll use an example scenario to illustrate: let’s say we need to capture a deep URL http://server.com/#/xyz requested by an unauthenticated user so that they can be redirected to that deep URL post-login.

  1. The unauthenticated user requests http://server.com/#/xyz (everything from the ‘#’ onwards is not sent to the server).

  2. All the server knows is that the user wants http://server.com/ and that they are unauthenticated. Server redirects the user to a login form.

  3. Here’s the clever bit: the client is still waiting on their original request so if the server includes a hidden element in the login form with some JS that references window.location.href, it can capture the full URL of the original request complete with the anchor portion:

    <form action="/login" method="post">
      <div>
        <label>Username:</label>
        <input type="text" name="username"/><br/>
      </div>
      <div>
        <label>Password:</label>
        <input type="password" name="password"/>
      </div>
      <!-- XXXXXXXXX CLEVER BIT XXXXXXXXXX-->
      <script>
        document.write('<input type="hidden" name="from" value="'+document.location.href+'"/>');
      </script>
      <!-- XXXXXXXXXX-->
      <div>
        <input class="submit-button" type="submit" value="Submit"/>
      </div>
    </form>
    
  4. The user authenticates themself and the original URL is sent with the POST. The server can then relay the user to the original deep URL.

Leave a Reply

Your email address will not be published. Required fields are marked *