Amresh Venugopal
Amresh Venugopal

Reputation: 9549

MEAN: Loggin in by JWT

[Q1] What advantage does an HTTP Interceptor provide on modifying the config.headers["Authorization"] (frontend AngularJS) to contain the value of token when I can verify the requests by checking the req.cookies object? (at the backend NodeJS)

I am trying to understand how JSON web tokens function. The demo application I have setup has a login functionality.

  1. On GET '/login' I am able to produce a token, set a cookie with it.
  2. On the frontend, I can access a JSON object containing the token.
  3. I can view the cookie in the developer console.

Nodejs:

index.js - login route

router.post('/login', function(req, res, next) {
  Authenticator.find(req.cookies.token, req.body, Heartbeat.common, function(err, warning, data){
    if(err) {
      res.status(404).send({token:false, warning: null, error:err});
    } else if(warning){
      res.status(200).send({token:true, warning: warning, error:null});
    } else {
      res.cookie('token', data, {maxAge: 3600000, httpOnly:true});
      res.status(200).json({token:true, error: null});
    }
  });
});

Authenticator.ctrl.js - Authenticator.find()

find: function(token, user, heartbeat, callback) {
  if(!token) {
    Auth.findOne({email:user.email}, function(err, data){
      if(err) {
        console.log(err);
      } else {
        if(data) {
          if(data.checkHash(user.password)) {
            callback(null, null,TokenMaker.createToken(user.email, heartbeat));
          } else {
            callback(Errors.login.strict.MISMATCH, null, null);
          }
        } else {
          callback(Errors.login.strict.NOT_REGISTERED, null, null);
        }
      }
    });
  } else {
    callback(null, Errors.login.warning.ACTIVE_REFRESH, null);
  }
},

Angular Controller

app.controller('userAccessCtrl', ['$scope', '$http', function ($scope, $http){
  $scope.user = {
    email: "[email protected]",
    password: "12345679"
  };
  $scope.error = {};
  $scope.loginAccess = function(user) {
    var submitReady = true;
    var emailStatus = EmailValidator.email(user.email);
    var passwordStatus = EmailValidator.password(user.password);
    if(typeof emailStatus === "string") {
      $scope.error.email = emailStatus;
      submitReady = false;
    }
    if(typeof passwordStatus === "string") {
      $scope.error.password = passwordStatus;
      submitReady = false;
    }
    if(submitReady) {
      $scope.error = {}
      var data = $scope.user;
      $scope.user = {};
      $http.post('/login', data)
        .then(function(success){
            console.log(success);
          },function(error){
            console.log(error);
        });
    }

}
}]);

Console response:

{
  "data": {
    "token":true,
    "error":null
  },
  "status":200,
  "config":{
    "method":"POST",
    "transformRequest":[null],
    "transformResponse":[null],
    "url":"/login",
    "data":{
      "email":"[email protected]",
      "password":"12345679"
    },
    "headers":{
      "Accept":"application/json, text/plain, */*",
      "Content-Type":"application/json;charset=utf-8"
    }
  },
  "statusText":"OK"
}

Upvotes: 0

Views: 168

Answers (1)

sergiy.dragunov
sergiy.dragunov

Reputation: 790

Actually it's a wrong to use cookies and JWT tokens. JWT token is much better for authentication than cookies. When you use token, your server doesn't need to store session in database of memory and this is a big advantage for your application - you can scale you application, add new servers without thinking about how to sync sessions between servers.

In short words, when you use JWT token your flow is next:

  • frontend (in you case it's an angular) sends login and password to /login route
  • backend checks credentials and sends back token (in request body, not in cookies)
  • frontend app saves token in local storage or session storage of browser
  • and you can write HTTP Interceptor which will intercepts all requests to backend and it will attach "Authorization" header to all requests, it looks like next:

    Authorization: Bearer here-is-your-jwt-token

  • backend can check this authorization header and if it is correct (look at http://jwt.io to read how verification works) backend can serve you request.

Upvotes: 1

Related Questions