JWT无法解码"JWT格式错误" - Node Angular

7
登录后,我会向客户端发送一个JSON Web Token。我有一个自定义的authInterceptor,它将JSON Web Token发送回服务器端。当我登录时,一切都正常。转到不同的子页面,非常好用。这是因为我有一个函数,它检查Passport身份验证或令牌身份验证,并且在登录时,Passport身份验证有效。当我关闭浏览器并返回网站时,JWT无法解码。当JWT放置在编码函数下面时,它可以解码。我尝试了jwt-simple节点模块和jsonwebtoken节点模块,但遇到相同的错误。以下是我的自定义函数,它检查是否存在有效的令牌:
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使用jwt.encode()jwt.decode(),而jsonwebtoken使用jwt.sign()jwt.verify()。这是我在控制台中得到的:

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

我是客户端的authInterceptor。我会收集令牌并将其设置在请求头中:

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);
    }
};
});

1
你在 catch 块中使用 console.log 输出了错误吗? - Bennett Adams
1
新手错误,我本应该这样做。这就是我得到的结果:{ [JsonWebTokenError: jwt malformed] name: 'JsonWebTokenError', message: 'jwt malformed' } - Les Paul
1
我不确定这是否与您有关,但是 JSON Web Token 应该是 req.headers.Authorization 的整个内容,因此当您 split('.') 并获取索引为 1 的元素时,实际上是负载,所以您拥有将变量 token 引用到负载而不是完整的 JWT。如果您之前没有使用过 JWT,此 toptal 文章 对它们有很好的解释。 - Bennett Adams
你说得太对了!这是我之前的代码:var token = req.headers.authorization.split('.')[1];但实际上应该改成:var token = req.headers.authorization.split(' ')[1];这样就可以把Bearer那部分去掉,只保留token了!如果你想手打答案的话,我会给你相应的奖励。 - Les Paul
1个回答

12
很高兴你解决了问题!为了后人着想,问题如下: JWT 由三个组件组成,即头部、载荷和签名(在这篇 toptal 文章中可以找到一个好的详细解释),所以当你使用 var token = req.headers.authorization.split('.') 将 JWT 拆分成组件时,你赋给 token 的值仅仅指代载荷而非完整的 JWT。
因为 jwt-simple 解码方法需要完整的令牌,而你只提供了载荷来评估,所以你的代码会触发“JWT 格式不正确”的错误。在你的情况下,由于你在授权标头中加入了 Bearer,你可以使用 var token = req.headers.authorization.split(' ') 来获取完整的令牌。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接