About the Author

Academic:

  • BA in Political Sci. & Int. Relations from Bosphorus Univ.
  • BS in CS from Oregon State Univ.
  • MSCS Student @ Georgia Tech.

Open Source:

  • ZF2 Contributor
  • Phing Contributor
  • Original Author of Phrozn

Conferences:

  • Zend Framework Day 2010, 2011 (Kiev, Ukraine)
  • ZF Conf Russia 2012 (Moscow, Russia)
  • EuroPython 2014 (Berlin, Germany)

Introduction

Presentation Outline

  • AngularJS Overview
  • REST: Refresher Course
  • Use Case in Focus: Authentication
  • Common Problems (with Solutions)
  • Concluding Remarks

Introduction

Sample Application Setup

  • Setup is done using Vagrant + Ansible
  • 3 nodes, 3 separate protection domains
    • App Server
    • DB Server
    • API Server

Introduction

Part 1

AngularJS Overview

http://thatguywiththeglasses.com/blogs/latest/entry/dangerous-creatures-cape-buffalo

Top 5 Killer Features of AngularJS

  • Modularity
  • Dependency Injection
  • Data binding
  • REST $resource
  • Amazing use of Promises API

Part 1: AngularJS Overview

Modularity

Define your service:

// app/scripts/services/test.js
angular.module('demoApp')
  .service('Test', function Test() {
    this.yell = function () {
      console.log('hello!');
    };
  });

Use the service:

// app/scripts/controllers/main.js
angular.module('demoApp')
  .controller('MainCtrl', function ($scope, Test) {
    Test.yell();
  });

Part 1: AngularJS Overview

Data Binding

Setup view:

<div class="jumbotron">
    <p ng-show="name">Hello, {{ name }}</p>
    <input type="text" ng-model="name"/>
</div>

Setup scope:

// app/scripts/controllers/main.js
angular.module('demoApp')
  .controller('MainCtrl', function ($scope) {
    $scope.name = 'Alex';
  });

Part 1: AngularJS Overview

REST Support - $http

Nothing fancy (on surface):

$http({method: 'GET', url: '/someUrl'}).
    success(function(data, status, headers, config) {
      // this callback will be called asynchronously
      // when the response is available
    }).
    error(function(data, status, headers, config) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
    });

Until we realize that $http returns promise:

var responsePromise = $http.get('/someUrl');
responsePromise.
    then(function (response) { // promise resolved
      $scope.data = response.foo;
    }, function (reason) { // promise rejected
      throw new Error(reason);
    });

Part 1: AngularJS Overview

REST Support - $resource

Define your RESTful Resource:

angular.module('demoApp', ['ngResource', 'ngRoute'])
  .factory('Event', function ($resource) {
    return $resource('https://api.rest.tickets/secured/events/:id');
  });

Consume $resource-enabled service:

angular.module('demoApp')
  .controller('EventsCtrl', function ($scope, Event) {
    // GET /secured/events?foo=bar
    Event.query({'count': 10}, function (data) {
      $scope.events = data;
    });
    // GET /secured/events/42
    Event.get({id: 42}, function (data) {});
    // POST /secured/events with `data` as payload
    Event.save(data);
    // DELETE /secured/events/42
    Event.delete({id: 42});
  });

Part 1: AngularJS Overview

Promises: Deferred API

function asyncGreet(name) {
    var deferred = $q.defer();

    setTimeout(function() {
      scope.$apply(function() {  // make sure that changes are observed
        deferred.notify('About to greet ' + name + '.');

        if (okToGreet(name)) {
          deferred.resolve('Hello, ' + name + '!');
        } else {
          deferred.reject('Greeting ' + name + ' is not allowed.');
        }
      });
    }, 1000);

    return deferred.promise;
}

var promise = asyncGreet('Robin Hood');
promise.then(
    function(greeting) { alert('Success: ' + greeting); },
    function(reason) { alert('Failed: ' + reason); },
    function(update) { alert('Got notification: ' + update); }
);

Part 1: AngularJS Overview

Callback Hell

Problem: Synchronize multiple asynchronous functions.

Solution (sort of):

// see http://fdietz.github.io/recipes-with-angular-js
// for more amazing examples
tmp = [];
$http.get("/app/data/first.json").success(function(data) {
  tmp.push(data);
  $http.get("/app/data/second.json").success(function(data) {
    tmp.push(data);
    $http.get("/app/data/third.json").success(function(data) {
      tmp.push(data);
      $scope.combinedNestedResult = tmp.join(", ");
    });
  });
});

Part 1: AngularJS Overview

Promises: Avoid Callback Hell

Aggregating promises:

var first  = $http.get("/app/data/first.json"),
    second = $http.get("/app/data/second.json"),
    third  = $http.get("/app/data/third.json");

$q.all([first, second, third]).
    then(function(result) {
      var tmp = [];
      angular.forEach(result, function(response) {
        tmp.push(response.data);
      });
      return tmp;
    }).
    then(function(tmpResult) {
      $scope.combinedResult = tmpResult.join(", ");
    });

Part 1: AngularJS Overview

Tools Infrastructure

  • Yeoman:
    • yo - scaffolding tool
    • bower - package management
    • grunt - the build tool
  • Jasmine + Karma for testing.
  • Batarang chrome extension.

Part 1: AngularJS Overview

Part 2

REST: Refresher Course

Brief History of REST

  • Fielding's dissertation
    sorry, I know that everybody mentions it!
  • Some ACM papers stats (not very representative!):
    • REST keyword is in 200K+ papers
    • RESTful keyword is in 2K+ papers
  • Many books on topic (both from academic - hello Prof. Pautasso - and expert perspectives)
  • Countless of talks, presentations, and tutorial sessions (not that amazing as this one!).

Part 2: REST Refresher Course

Thinking in Resources

  • Resource := type + associated data + relationships + methods
  • Resource Types
  • Resources and Identifiers
    • URIs & URLs
  • Resources and Representations
  • Representation Encoding Formats:
    • JSON
    • XML
  • Resource Relationships

Part 2: REST Refresher Course

HATEOAS

  • HATEOAS := Hypertext As The Engine Of Application State.
  • State machine with no prior knowledge of possible states.
  • Crucial part of Uniform Interface constraint.
  • Almost totally ignored by all API providers (this slowly changes).

Part 2: REST Refresher Course

Architectural Constraints

REST Architectural Constraints:

  • Client-server
  • Stateless
  • Cacheable
  • Layered System
  • Uniform Interface
    • Identification of resources
    • Manipulation of resources through representations
    • Self-descriptive messages
    • Hypermedia as the engine of application state (HATEOAS)

Part 2: REST Refresher Course

Methods

Method https://api.rest.tickets/events https://api.rest.tickets/events/42
GET List collection members. Get member representation.
PUT Replace collection. Replace the addressed member.
POST Add new member. Not used (if resource is not a collection itself).
DELETE Delete entire collection. Delete the addressed member.

Part 2: REST Refresher Course

Status Codes

Bare minimum status codes:

Method On Success On Failure
GET 200 Ok 400 Bad Request
404 Not Found
PUT 200 Ok + representation
204 No Content
400 Bad Request
404 Not Found
DELETE 204 No Content 400 Bad Request
404 Not Found
410 Gone
POST 201 Created + Location 400 Bad Request

Part 2: REST Refresher Course

Part 3

Case in Focus: Authorization

Challenges

  • Authentication is really hard (I MEAN it)
  • Browser restrictions
  • Plethora of competing specs
  • Keeping private keys private
  • Use standards, auth is not a nice sandbox for creativity

Part 3: Case in Focus

Same Origin Policy

Possible Solutions:

  • JSONP
  • Proxy
  • CORS (Cross Origin Resource Sharing)

Part 3: Case in Focus

Client/Server: Communicating secrets

Possible ways to communicate secret from client to server:

  • HTTPS + BASIC authentication ("Authorization: Basic ..." header in each request)
  • Signing requests Amazon-style ("Authorization: AWS ... " header in each request)
  • OAuth: acquire Access Token, include that and a bunch of other parameters in each request
  • Cookie that stores session key ("Cookie: ... " header in each request)
  • Signed cookie that stores session information in the cookie itself

Part 3: Case in Focus

Basic Auth

Server wants client to authenticate itself:

        401 Unauthorized
        WWW-Authenticate: Basic realm="Secure Area"

Client uses Authorization: header to provide credentials:

        Authorization: Basic base64_encode("username:password")

Notes:

  • Browser is responsible for preserving/caching of credentials
  • For how long do credentials get cached - browser-dependent.
  • If client knows that page is protected, it can include identify itself immediately
  • Run this thing behind the SSL.

Part 3: Case in Focus

Digest Auth

Server wants client to authenticate itself:

        401 Unauthorized
        WWW-Authenticate: Digest realm="Secure Area" nonce="md5 hash" qop="auth"

Client need to respond with Authorization: containing hashed secret:

        Authorization: Digest username="client1", realm="Secure Area",
            nonce="server nonce", response="hashed secret will be here",
            cnonce="client nonce", uri="/events" nc=000000001, qop="auth"

Notes:

  • A1 = md5(username + realm + secret)
  • A2 = md5(method + uri) or A2 = md5(method + uri + md5(body))
  • Response = md5(A1 + nonce + A2)

Part 3: Case in Focus

OpenID 1.0, 1.1 + OpenID 2.0

  • OpenID is about Authentication
  • Defines protocol between RPs and IdPs
  • OpenID provides a way to prove that an End User owns an Identity URL.
  • No password, email address, or anything is passed around.
  • Completely decentralized i.e. anyone can be a Consumer or Identity Provider.
  • OBSOLETE!

Part 3: Case in Focus

OAuth

  • Access granting protocol
  • Principle specs:
    • OAuth 2.0 Authorization Framework (RFC6749)
    • OAuth 2.0 Authorization Framework: Bearer Token usage (RFC6750)
  • OAuth 2.0 Specification got so complicated that one of its principle authors resigned in process!

Part 3: Case in Focus

OpenID Connect

  • Based on OAuth2
  • Email is used as identifier (finally!)
  • Specification is 19 sections in length, we are not after simplicity here!
  • Has a true notion of identitIES
  • As of Feb 26, 2014 OpenID Connect Specification is launched!!! It is new, shiny, great! Everbody wants to use it..

Part 3: Case in Focus

Bearer Token Authentication

What if we are not interested in:

  • decentralization
  • authenticating using 3rd party OpenID Providers

Are happy with:

  • plain old username/password type of authentication (at least for the first release)

Don't want to:

  • deal with the complexity associated with correct integration of OpenID Connect
  • to implement complex Authorization Server (granting access to resource using scopes etc), all we need is access (and user role is associated dynamically on server)

Part 3: Case in Focus

Bearer Token Authentication

Objectives:

  • The OAuth 2.0 Authorization Framework: Bearer Token Usage
  • HTTP 1.1 + TLS

OAuth Workflow:

  • Client asks for authorization grant from resrouse owner
  • Client exchanges authorization grant, for access token
  • Access token := scope + duration + other attribs of the grant
  • Access token is presented when resource is accessed

OAuth Alternative Workflow:

  • Client directly presents its credentials to authorization server
  • Authorization server grants access token

Part 3: Case in Focus

Bearer Token Authentication

Server asks for authorization:

        HTTP/1.1 401 Unauthorized
        WWW-Authenticate: Bearer realm="some opaque string"
                                 scope="space delimited CaSE sensitive scope values"

If authentication failed:

        HTTP/1.1 401 Unauthorized
        WWW-Authenticate: Bearer realm="example",
                          error="invalid_token",
                          error_description="The access token expired"

Notes:

  • POST http://your.api.com/authentication for login
  • DELETE http://your.api.com/authentication for logout

Show some code!

Part 3: Case in Focus

Part 4

Common Problems

Part1

  • Implementing CORS
  • Content Negotiation
  • API Versioning
  • Pagination
  • Queries

Part 4: Common Problems

Part1

  • Request Limits
  • API Documentation
  • Transactions
  • Race Conditions

Part 4: Common Problems

Thank You!