Creating an AngularJS application with user authentication
April 09, 2014
Creating an authentication system within a Single Page App (SAP) can be a bit tricky; hopefully this post will help alleviate some of the challenges. Before you begin, it's a good idea to set up your environment so as to decouple the front and backends. There's a good post explaining the process over at StackOverflow. (The StackOverflow answer deals with a Laravel backend, but the code is easily modified for any other backend service.)
Our application will be structured as follows:
Let's start with our basic index.html setup:
There are a few things going on here... First, we declare this DOM as an AngularJS app named "auth_demo." Second, we create a user-info DIV (which will only be shown when the ng-show directive's expression evaluates to true), bind the user_email variable, and provide a logout link which will trigger the logout() function on click. Finally, we use the ng-view directive to display the content for our menu route, and then load the various JavaScript files required by our app.
Now we can create our basic App (in app.js), routing a few paths to appropriate controllers and partials:
Note that we declare ngRoute as a dependency for our App, and use the resolve object property to map dependencies that will be injected into the controller. Our isAnon and isAuth dependencies will be promises, and Angular's router will wait for them to be resolved or rejected before instantiating the controller. This means we can use them as a sort of "filter" to control access to our routes.
Now we will create the isAuth and isAnon promises:
Both of the promises perform a GET request against /ws/api/v1/auth
and work with the returned JSON. Our example backend will return a JSON object which will contain
a string status property (set to either ok or error), a boolean auth
property (current authentication state), and a string user_email property. Depending on the values in returned JSON, the promises will either resolve or reject.
Now that the promises are set up (and the backend is returning the appropriate JSON response) we can
create the login form in partials/login.html:
This form creates two textfields, binds their values to a form_data object, and calls
the process() function upon form submission.
Next up is the the loginController we refenced in our route provider. Declare it in
controllers/loginController.js, and don't forget to load the file in your index.html.
You'll note that the controller uses a (so far undefined) service called authService. Let's
create it in services/authService.js...