Nodejs Restify - 使用 jwks 验证 Jwt id_token

Nodejs Restify - Valide Jwt id_token with jwks

我们开发了一个应用,前面是VuejS,后面是apiNodejs(Restify)。 我们使用第三方为我们提供身份验证(使用 OpenId Connect 协议的身份提供者)。

因此,使用 VueJs 我们可以进行身份​​验证,获取 access_tokenid_token 并将其传入每个 nodejs 请求 header with bearer.

现在我们需要在后面验证此令牌是否有效以及用户是否可以访问此路由。

我们的身份提供商为我们提供了一个端点 (jwks_uri),其中的键如下:

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "AXDJKLFJDLKFJLKJFLKSJDFLKJSFL",
      "e": "AQAB",
      "n": "2T3QDw6gcSDFS........................VRtQSDQSDQSDQSD"
    }
  ]
}

我从中提取了 public 密钥,结果类似于:

-----BEGIN PUBLIC KEY-----
MIIB......................OCAQ8AMIIBCgKCAQEA2T3QDw6gcqrTZRy74XWy
Bn0JoQzg/H2QX.............................................fqX13O
4QIDAQAB
-----END PUBLIC KEY-----

现在我想用这个 public 密钥验证 id_token 我尝试这样的事情

jwt.verify(token, publicKey, { algorithms: ['RS256'] }, function(err, decoded) {
    //This will display the decoded JWT token.
    console.log(decoded)  
});
  1. 但是我不知道如何正确使用验证来检查有效性? 声明 ?

  2. 我想要的每条路每次都要重做同样的处理吗 保护?是这样的吗?

server.get('/data1', async function (req, res, next) {
    try {
        helper.validAccessToken(req).then(function(res) => {
            if(res){
                data=getData();
                res.send(data) ;
            } else{
                res.send(401, {message: 'Unauthorizd'}) 
            }
        });
    } catch (err) {

        return next(err);
    }
});

我认为中小型应用程序的最佳方式就是让 jwt 验证作为中间件工作。类似于:

// authUser.js

module.exports = function authUser(req, res, next) {
    const token = getJwtToken(req)
    jwt.verify(token, publicKey, { algorithms: ['RS256'] }, function(err, decoded) {
        if (err) {
          res.send(401, 'Unauthorized')
          return next(false)
        }
        return next()
    })
}

并将其包含到您要限制访问的路由的中间件链中。

server.get("/secure", authUser, function (req, res, next) {
  res.send(200, "secure route response");
  return next();
});

server.get("/", function (req, res, next) {
  res.send(200, "public route response");
  return next();
});

codesandbox link

对于大型应用程序,我相信您需要更灵活和可配置的东西。能够引入不同的安全级别和身份验证策略。以及更灵活的路由配置。

最后我被你的提议感动了。

我实现了一个检查令牌并添加请求属性的功能。这个功能我用作“中间件”

 async function authUser(req, res, next) {
  try{    
    req.isLogged=false
    console.log(req.params);
    let isvalid = await validAccessToken(req);
    console.log(">>> isValid : " + isvalid);
    if(isvalid===true){
      //token verifié on passe en preview false
      req.isLogged=true
      return next()
    }else{
      console.log("Unauthorized");
      req.isLogged=false
      return next()                
    }
  }catch(error){

    res.send(401, 'Unauthorized ' + error)
    return next()
  }
}

我把函数像中间件一样放在了 restify 服务器中:

server.use(openid.authUser);

在此之后,在我想要保护的每条路线中,我检查这个属性:

const preview = ! req.isLogged ;