Authentication

and

Authorization

in

Angular

Objectives

  • Review classical authentication flow

  • Solidify distinction between tokens and cookies

  • Use angular packages to send secure/authorized information using JWT

  • Create the feeling of a "session" without cookies

Classical Authentication

Client

Server

1. Client sends user/password

Classical Authentication

Client

Server

1. Client sends user/password

2. Server validates user/pass and upon success creates a cookie

Classical Authentication

Client

Server

1. Client sends user/password

2. Server validates user/pass and upon success creates a signed cookie

3. Server sends cookie

Classical Authentication

Client

Server

1. Client sends user/password

2. Server validates user/pass and upon success creates a signed cookie

3. Server sends cookie

4.
All further communication

involves the signed cookie

Classical Authentication

Client

Server

1. Client sends user/password

2. Server validates user/pass and upon success creates a signed cookie

3. Server sends cookie

4.
All further requests

send the signed cookie

5.

All further requests check the cookie

Token Authentication

Client

Server

1. Client sends user/password

2. Server validates user/pass and upon success creates a JWT (which are signed)

3. Server sends JWT

4.
All further requests

send the JWT

5.

All further requests check the JWT

Those Look The Same

  • Established best practices for securing information have not changed much even since paper based cryptography.
     
  • What has changed is the mechanism for keeping the secret.
     
  • JWTs and Cookies are different standards that behave differently in implementation, but similarly in concept.

So What Matters?

Crucially: a client needs to be able to hold information that uniquely identifies it, but that could not be recreated by a 3rd party attacker.

 

Then why change?

JWT was invented specifically to deal with cases where cookies do not work well.

 

Single Page App + Service Oriented Architecture is an example of such a case. 

Implementation

  1. Interceptors on the front end
  2. login + Middleware on the back end
  3. Joy

"Interceptors": Request

Interceptors are the middleware of angular.

Angular Client:

Initial HTTP

Request

Interceptor

Server

"Interceptors": Response

Interceptors are the middleware of angular.

Angular Client:

Initial HTTP

Request

Interceptor

Server

"Interceptors": The Code

app.config(function($routeProvider, $httpProvider){
  $httpProvider.interceptors.push('testInterceptor');
})

Step 1: register your interceptor with $httpProvider

This is a service that we are about to create

"Interceptors": The Code

.service('testInterceptor', function testInterceptor(){
  return {
    request: function(config){
      return config;
    },
    requestError: function(err){
      return err;
    },
    response: function(response){
      return response;
    },
    responseError: function(err){
      return err;
    }
  };
})

Step 2: Create the "interceptor service"

"Interceptors": The Code

myApp.service('testInterceptor', function testInterceptor(){
  return {
    // An interceptor that is called when making
    // a request. The config object is the same
    // type of object used when calling $http(config)
    request: function(config){
      return config;
    }
  };
})

Step 2.5: Types

Request interceptor

"Interceptors": The Code

myApp.service('testInterceptor', function testInterceptor(){
  return {
    // An interceptor that runs when $http
    // or another interceptor encounters an
    // error. The input is that error.
    requestError: function(err){
      return err;
    }
  };
})

Step 2.5: What are these?

Request Error interceptor

"Interceptors": The Code

myApp.service('testInterceptor', function testInterceptor(){
  return {
    // An interceptor that runs when a 
    // response is received. The parameter
    // here is the data from that response.
    response: function(response){
      return response;
    }
  };
})

Step 2.5: What are these?

Response Interceptor

"Interceptors": The Code

myApp.service('testInterceptor', function testInterceptor(){
  return {
    // An interceptor that runs when 
    // an error occurs during another
    // interceptor. *NOT* if the response
    // object itself is erroneous (404/500)
    responseError: function(err){
      return err;
    }
  };
})

Step 2.5: What are these?

Response Error Interceptor

"Interceptors": The Code

// Somewhere in the login code:
var loginPromise = $http({
    method: "POST",
    url: "/login",
    data: {user: "teb", password: "123456"}
});

loginPromise.then(function(response) {
     // Assuming this is how your server responds
    if(response.data.jwt) {
        localStorage.set('token', response.data.jwt);
    }
});

Step 3: If you login successfully -- store JWT

"Interceptors": The Code

myApp.service('testInterceptor', function testInterceptor(){
  return {
   request: function(config){
      var token = localStorage.getItem("token");
      
      if(token) {
        config.headers.Authorization = "Bearer " + token;
      }

      return config;
    }
  };
})

Step 4: Use an Interceptor for JWT tokens

Ask local storage if there is a JWT -- if there is then always throw it in the authorization header

Questions?

Questions for you

SURPRISE

Get a whiteboard, and draw the steps for JWT authorization. Explain it to your neighbor!

Made with Slides.com