实现基于JWT的身份验证,不使用Oauth和自定义令牌方案

时间:2017-11-09 23:00:38

标签: express authentication jwt

我正在开发一个Web API,我在其中实现了基于JWT的身份验证。我既没有使用PasswordJS middlware也没有使用Oauth协议。它基本上是JWT npm,我用它来签署和验证令牌。

令牌的整个概念非常清楚,但我对“令牌方案”一词非常困惑,无法理解它的用途。

我想要了解的是:我是否需要使用某种排序或自定义'JWT'方案并在将令牌发送回服务器以进一步请求时验证它,或者此概念仅由Oauth使用,以及我是什么需要的只是发送普通令牌?

var accessToken = jwt.sign({
    userID: user.id,
    isAdmin: user.isAdmin
}, config.userSecret, {
    expiresIn: 600 
});

res.json({
    success: true,
    user: {
        id: user._id,
        name: user.name,
        username: user.username,
        accessToken: 'JWT ' + accessToken, 
    }
});


jwt.verify(accessToken, secret, function(err, token){...}); //throws error when token is passed with the custom scheme

1 个答案:

答案 0 :(得分:1)

在这种情况下,您所使用的方案究竟是什么并不重要,因为您无论如何都要手动解析授权标头的内容。

基本上,令牌从客户端发送到名为 Authorization 的HTTP头上的服务器。在令牌前面放置了方案的名称。因此 Authorization 标头可能如下所示:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

(允许的名称列表为here。对于JWT,它通常是承载。从技术上讲,您根据RFC6749不遵循OAuth 2.0承载方案,但它&# 39;无论如何,通常称为Bearer。)

您必须手动获取令牌(ey ...)并使用jwt.verify()进行验证以获取其有效负载。

const headerExists = req.headers.authorization

if (headerExists) {
  let token = req.headers.authorization.split(' ')[1];

  jwt.verify(token, auth.secretjwtkey, function (err, decoded) {
    if (err) {
      res.status(HttpStatus.UNAUTHORIZED).json('Unauthorized');
    } else if (decoded.role === 'admin') {
      next();
    } else {
      res.status(HttpStatus.UNAUTHORIZED).json('Unauthorized');
    }
  })
} else {
  res.status(HttpStatus.FORBIDDEN).json('No token');
}

您可以从上面的示例中间件中看到,我并不关心授权标头上的 Bearer 字符串,只关注令牌本身。当然,您可以检查它实际上是 Bearer 而不是其他东西。

故事的寓意是:

  • 您可以在授权标头上将令牌从客户端发送到服务器。你必须设置前端才能发生这种情况。
  • 您在令牌前面加上 Bearer (或允许列表中的其中一个,但建议使用持票人。)
  • 您可以通过阅读授权标题上的字符串的第二部分来解码该令牌,然后将其提供给jwt.verify()

有关详细信息,请参阅here