Authentication for single page apps can be a tricky matter. In many cases, SPA architecture involves having an isolated front-end application with a framework like AngularJS, and a separate backend that serves as a data API to feed the front-end. In these cases, traditional session-based authentication that is done in most round-trip applications falls short. Session-based authentication has a lot of issues for this kind of architecture, but probably the biggest is that it introduces state to the API, and one of the tenets of REST is that things remains stateless. Another consideration is that if you ever want to use that same data API as a backend for a mobile application, session-based authentication won't work.
JSON Web Tokens
[author_more]
To get around these limitations, we can use JSON Web Tokens (JWT) to add authentication to our single page apps. JWT is an open standard and provides us a way to authenticate requests from our front end AngularJS app to our backend API. JWTs are more than just a token though. One of the biggest advantages of JWTs is that they include a data payload that can have arbitrary JSON data in the form of claims that we define. Since JWTs are digitally signed with a secret that lives on the server, we can rest assured that they can't be tampered with and the data in the payload can't be changed before reaching the backend.
Authentication for Angular Apps
JWTs are a perfect solution for adding authentication to our AngularJS apps. All we need to do to access secured endpoints from our API is save the user's JWT in local storage and then send it as an Authorization
header when we make HTTP requests. If the user has an invalid JWT or no JWT at all, their request to access the protected resoures will be denied, and they will get an error.
Unfortunately, this would be just the bare minimum for handling authentication in AngularJS apps. If we care at all about user experience, there are a few other things we need to do to make sure our apps behave as one would expect. We need to:
- Conditionally show or hide certain elements depending on whether the user has a valid JWT (e.g.: login and logout buttons)
- Protect certain routes that an unauthenticated user shouldn't be able to access
- Redirect the user to the home or login state if their JWT expires or when they log out
In this article, we'll implement authentication from start to finish in an AngularJS app, and we'll even create a small NodeJS server to see how to make requets to a protected resource. There are a lot of details around setting up a user database and issuing JWTs, so instead of doing it on our own, we'll use Auth0 to do it for us. Auth0 provides a free plan for up to 7,000 active users, which gives us plenty of room in many real world applications. We'll also see how we can easily add a login box and even use social authentication with Auth0.
To see all the code for this tutorial, check out the repo.
Sign up for Auth0
The first thing you'll need for this tutorial is an Auth0 account. When signing up for an account, you will need to give your app a domain name which cannot be changed later. Since you can have multiple apps under the same account, how you name your domain will depend on your situation. In most cases, it's best to name it with something that is relevant to your organization, such as your company's name. If it makes sense, you can also use your application's name--it's up to you. Your Auth0 domain takes the pattern your-domain.auth0.com
and is used when configuring the Auth0 tools that we'll see below.
Once you've signed up, you'll be asked what kind of authentication you'd like for your application. It's fine to leave the defaults in place, as you'll be able to change them later.
After you have signed up, head over to your dashboard to check things out. If you click the Apps / APIs link in the left sidebar, you'll see that your account gets created with a Default App. Click the Default App to see your credentials and other details.
Right off the bat we should fill in our Allowed Origins. This field is used to tell Auth0 which domains are allowed to make requests to authenticate users. We'll be using http-sever in this tutorial, which has a default origin of http://localhost:8080.
With Auth0's free plan, we are able to use two social identity providers, such as Google, Twitter, Facebook and many others. All we need to do to make them work is flip a switch and this can be done in the Connections > Social link in the dashboard.
Install the Dependencies and Configure Auth0
We'll need a number of packages for this app, some of which are provided by Auth0 as open source modules. We'll also use Angular Material to get some nice styling.
# Angular related modules
npm install angular angular-material angular-ui-router angular-aria angular-animate
# Auth0 related modules
npm install angular-jwt angular-storage auth0-angular
# To serve the app (if not already installed)
npm install -g http-server
Next, let's set up our app.js
and index.html
files to bootstrap the application. At this time we can let Angular know which modules we need access to from the dependencies we installed.
// app.js
(function() {
'use strict';
angular
.module('authApp', ['auth0', 'angular-storage', 'angular-jwt', 'ngMaterial', 'ui.router'])
.config(function($provide, authProvider, $urlRouterProvider, $stateProvider, $httpProvider, jwtInterceptorProvider) {
authProvider.init({
domain: 'YOUR_AUTH0_DOMAIN',
clientID: 'YOUR_AUTH0_CLIENT_ID'
});
});
})();
Here we've configured authProvider
from auth0-angular with our credentials from the dashboard. Of course, you'll want to replace the values in the sample with your own credentials.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en" ng-app="authApp">
<head>
<meta charset="UTF-8">
<title>Angular Auth</title>
<link rel="stylesheet" href="node_modules/angular-material/angular-material.css">
<!-- Auth0 Lock script and AngularJS module -->
<script src="//cdn.auth0.com/js/lock-8.2.min.js"></script>
<!-- Setting the right viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>
<!-- TODO: create the toolbar and ui-view -->
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/angular-animate/angular-animate.js"></script>
<script src="node_modules/angular-aria/angular-aria.js"></script>
<script src="node_modules/angular-material/angular-material.js"></script>
<script src="node_modules/angular-jwt/dist/angular-jwt.js"></script>
<script src="node_modules/angular-storage/dist/angular-storage.js"></script>
<script src="node_modules/auth0-angular/build/auth0-angular.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>
</body>
</html>
Notice here that we're bringing in the Auth0Lock widget script from Auth0's CDN. This is the script that we'll need to show the login box that Auth0 provides. By setting the viewport like we have, we make sure that the widget shows up properly on mobile devices.
Continue reading %Easy AngularJS Authentication with Auth0%
by Ryan Chenkie via SitePoint
No comments:
Post a Comment