Andrew Cavanagh

Developer.  Project Architect.  Huge Nerd.

(not necessarily in that order)

It’s not unusual to have an application with an AngularJS front-end that requires some kind of server-side authentication for users. In one recent case I was working on an AngularJS application with a Laravel back end. The Laravel end handled all of the authentication. This worked well with the one caveat that if a user clicked on a link or bookmark that required authentication, they’d be redirected to the Laravel login page (yay), but after they logged in successfully they’d just end up at the homepage instead of at the link they were originally trying to get to (boo). In other words if they clicked on a link to http://example.com/app#/some-cool-page, after they logged in they’d get dumped to http://example.com/app#. Because AngularJS handles most of the in-app routing, everything after the # basically gets dropped by Laravel.

In looking for ideas on how to rectify this I came across a super-handy blog post. The method there worked great up until the end, where the redirect he recommends failed for me in Laravel 5.1 (the post was originally for 4.2, it may work as advertised there). I came up with the following adaptation that works quite well in Laravel 5.1.

The steps are basically these:

  • Use jquery to save the original path to a cookie
  • In the Laravel Auth Controller, re-write the session variable that contains the intended path with the full path from the cookie
  • Save the updated session variable and let Laravel handle the rest

Details: As per the post referenced above, I used the jquery.cookies.js library to help with the cookies. You could do it without that, obviously. The important piece here is to include a script on your login view that gets the location and sets it in a cookie. In my case, that looked like this:

(function(){
    'use strict';

    var intended = window.location.hash;
    (intended.length > 0) ? jQuery.cookie('intended', '/app' + intended) : jQuery.cookie('intended', '/app');

})();

The next step is to update your Laravel session with the correct path. Laravel stores the intended path in the session and wants to send you there anyway, it just loses the angular path. We’ve stored the full path in a cookie, so now what we do in the Laravel AuthController is check to see if that cookie is set, and if so use it to update the intended session variable with the correct path and let Laravel take care of the rest as per usual. So the constructor for the AuthController looks like:

    public function __construct(Request $request)
    {

        if(isset($_COOKIE['intended'])) {
            $this->setRedirect($request);
        }
    }

and the setRedirect method looks like this:

    protected function setRedirect($request) {
            $url             = $request->session()->get('url', 'default');    //get the url info from your session
            $intended        = (url($_COOKIE['intended']));   //get the url with the angular path that you stashed in a cookie
            $url['intended'] = $intended;  //set the 'intended' value of the url from the session to the angular path you got above
            $request->session()->put('url', $url);  //put the url info back into your session so it uses the new 'intended' value when it redirects you after login
    }

And that’s it. Now getting redirected through authentication won’t make you lose your way.


comments powered by Disqus