Authentication for Node.js App with Angular.js and iOS Clients Authentication for Node.js App with Angular.js and iOS Clients angularjs angularjs

Authentication for Node.js App with Angular.js and iOS Clients


I would use a token based authentication where you can send a token (automatically) with each request. You'll have to log in once, the server will provide you with a token which you can then use to send with each request. This token will be added to the HTML header, so that you don't have to modify each request to the browser.

You can set certain calls in the API so that they always need a token, while others might not be token protected.

For Express, you can use express-jwt (https://www.npmjs.org/package/express-jwt)

var expressJwt = require('express-jwt');// Protect the /api routes with JWTapp.use('/api', expressJwt({secret: secret}));app.use(express.json());app.use(express.urlencoded());

If you want to authenticate you can create this function in your express server:

app.post('/authenticate', function (req, res) {  //if is invalid, return 401  if (!(req.body.username === 'john.doe' && req.body.password === 'foobar')) {    res.send(401, 'Wrong user or password');    return;  }  var profile = {    first_name: 'John',    last_name: 'Doe',    email: 'john@doe.com',    id: 123  };  // We are sending the profile inside the token  var token = jwt.sign(profile, secret, { expiresInMinutes: 60*5 });  res.json({ token: token });});

And for protected calls something that starts with /api:

app.get('/api/restricted', function (req, res) {  console.log('user ' + req.user.email + ' is calling /api/restricted');  res.json({    name: 'foo'  });});

In your Angular application you can login with:

$http      .post('/authenticate', $scope.user)      .success(function (data, status, headers, config) {        $window.sessionStorage.token = data.token;        $scope.message = 'Welcome';      })      .error(function (data, status, headers, config) {        // Erase the token if the user fails to log in        delete $window.sessionStorage.token;        // Handle login errors here        $scope.message = 'Error: Invalid user or password';      });

And by creating an authentication interceptor, it will automatically send the token with every request:

myApp.factory('authInterceptor', function ($rootScope, $q, $window) {  return {    request: function (config) {      config.headers = config.headers || {};      if ($window.sessionStorage.token) {        config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;      }      return config;    },    response: function (response) {      if (response.status === 401) {        // handle the case where the user is not authenticated      }      return response || $q.when(response);    }  };});myApp.config(function ($httpProvider) {  $httpProvider.interceptors.push('authInterceptor');});

If you have to support old browsers which do not support local storage. You can swap the $window.sessionStorage with a library like AmplifyJS (http://amplifyjs.com/). Amplify for example uses whatever localstorage is available. This would translate in something like this:

    if (data.status === 'OK') {      //Save the data using Amplify.js      localStorage.save('sessionToken', data.token);      //This doesn't work on the file protocol or on some older browsers      //$window.sessionStorage.token = data.token;      $location.path('/pep');    }  }).error(function (error) {    // Erase the token if the user fails to log in    localStorage.save('sessionToken', null);    // Handle login errors here    $scope.message = 'Error: Invalid user or password';  });

And the authintercepter we swap for:

angular.module('myApp.authInterceptor', ['myApp.localStorage']).factory('authInterceptor', [  '$rootScope',  '$q',  'localStorage',  function ($rootScope, $q, localStorage) {    return {      request: function (config) {        config.headers = config.headers || {};        config.headers.Authorization = 'Bearer ' + localStorage.retrieve('sessionToken');        return config;      },      response: function (response) {        if (response.status === 401) {        }        return response || $q.when(response);      }    };  }]);

You can find everything except AmplifyJS in this article:

http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/


Have a look to the yeoman generator for angular and node? The generator-angular-fullstack have a very nice structure for user authentification using passport.

You can see an example here :

the code: https://github.com/DaftMonk/fullstack-demo

the result: http://fullstack-demo.herokuapp.com/

Hope it helps!


I use generator-angular-fullstack, the /api services are not secured, get your _id from /api/users/me, logout, and go to /api/users/your_id_here, you will figure out that the /api not secured.