为 api 访问生成安全令牌

los*_*ion 6 security authentication node.js jwt bearer-token

我需要生成一个用于访问 api 的安全令牌。用户将进行身份验证,成功身份验证后,我将需要生成一个令牌。

重要提示:我确实需要能够随时撤销用户对 api 的访问权限。

选项1:

我可以生成一个随机字符串并将其用作令牌。将令牌和用户存储在数据库中。当用户传递令牌时,我会检查数据库中的令牌,如果它存在就去......

这使我能够通过删除用户令牌来撤销访问权限。如果他们尝试重新登录并且令牌消失了,他们将无法访问。我还可以根据时间使数据库中的令牌过期。

我正在使用 nodejs 并且已经看到了这一点:

Node.js 中的安全随机令牌

require('crypto').randomBytes(48, function(ex, buf) {
  var token = buf.toString('hex');
});
Run Code Online (Sandbox Code Playgroud)

如果有人猜不到我​​生成的令牌,那真的安全吗?

选项 2:

使用 jwt 之类的东西。在 auth 上生成一个带有用户 ID 的 jwt。当用户在请求上传递该 jwt 时,我确保 jwt 是有效的,如果是这样,则获取用户 ID 并顺利进行。这似乎更安全,因为 jwt 可以防止篡改。

问题是撤销对 api 的访问。我可以将所有 jwts(直到它们过期)存储在数据库中,根据请求验证 jwt 并确保它在我的数据库中。如果我想撤销,我可以将它从数据库中删除。这里的缺点是我现在有验证 jwt 并查找它以确保它在我的数据库中的开销。

是否有使用 jwt 撤销访问的好方法?

dyl*_*nts 4

这个问题可能会在答案中引起很多意见,因此最终取决于您和您的安全要求。

我喜欢的一种解决方案是按照您建议的方式生成随机字符,并在其中包含用户拥有的内容(例如电子邮件地址或 ID)。然后还包括一个时间戳以了解它的生成时间。将这些东西连接在一起形成一个字符串(也许使用一些字符来分割各个部分)。所以你最终会得到类似的结果:

<random-string-of-characters>|<user-email-address>|<timestamp>
Run Code Online (Sandbox Code Playgroud)

现在加密该字符串,也许使用bcrypt之类的东西,并且该 blob 最终成为您所说的“令牌”。内部用户不必理解它,他们只需要存储它并稍后访问它以将其发送到您的安全层进行验证。您可以通过解密并验证各个部分来验证它。

该解决方案使您可以完全控制如何授予用户访问权限。您可以继续将生成的字符存储在数据库中并随时撤销它,或者查看时间戳以查看它们是否“超时”。

我想这个问题有很多解决方案,所以这只是其中之一:)