Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT not decoding "JWT malformed" - Node Angular

Upon logging in I send a JSON web token to the client-side. I have a custom authInterceptor which sends the JSON web token back to the server side.

When I log in, everything works. Go to different sub-pages, works great. This is because I have a function which either checks for Passport authentication or token authentication, and upon logging in the Passport authentication works.

When I close the browser and return to the site, the JWT cannot decode. The JWT can decode when it is placed just under the encoding function. I have tried both the jwt-simple node module and the jsonwebtoken node modules, and I come back with the same error.

This is my custom function which checks for a valid token:

function checkAuthentication(req, res, next){
  if (!req.headers.authorization) {
     return res.status(401).send({ message: 'Please make sure your request has an Authorization header' });
  }
  console.log("Here");
  var token = req.headers.authorization.split('.')[1];
  console.log(token);
  console.log(config.secret);
  var payload = null;
  try {
    console.log("And here....");
    payload = jwt.decode(token, config.secret);
    console.log(payload);
  }
  catch (err) {
    console.log(err);
    return false;
  }

  if (payload.exp <= moment().unix()) {
    return false;
  }
  req.user = payload.sub;
  return true;
}

jwt-simple uses jwt.encode() and jwt.decode, and jsonwebtoken uses jwt.sign() and jwt.verify(). This is what I get in my console:

Here
eyJzdWIiOiI1NmEyZDk3MWQwZDg2OThhMTYwYTBkM2QiLCJleHAiOjE0NTYxOTEyNzQsImlhdCI6MTQ1NTMyNzI3NH0
VerySecretPhrase
And here....
{ [JsonWebTokenError: jwt malformed] name: 'JsonWebTokenError', message: 'jwt malformed' } 

This is the authInterceptor on the client-side. I collect the token and set it in the request header:

app.factory('httpInterceptor', function($q, $store, $window) {
return {
    request: function (config){
        config.headers = config.headers || {};
        if($store.get('token')){
            var token = config.headers.Authorization = 'Bearer ' + $store.get('token');
        }
        return config;
    },
    responseError: function(response){
        if(response.status === 401 || response.status === 403) {
            $window.location.href = "http://localhost:3000/login";
        }
        return $q.reject(response);
    }
};
});
like image 811
Les Paul Avatar asked Feb 13 '16 01:02

Les Paul


1 Answers

Glad you got it figured out! The problem, for posterity, was the following: A JWT consists of three components, a header, the payload, and the signature (a good, thorough explanation can be found in this toptal post), so when you were splitting the JWT into components with var token = req.headers.authorization.split('.'), the value you were assigning to token referred to the payload only, rather than the full JWT.

Because the jwt-simple decode method expects the full token and you were only giving it the payload to assess, your code was triggering the 'jwt malformed' error. In your case, since you preceded the token with Bearer in your Authorization header, you could grab the full token with var token = req.headers.authorization.split(' ') instead.

like image 81
Bennett Adams Avatar answered Oct 02 '22 15:10

Bennett Adams