如何在 Node JS 中使用 jwt 授权具有不同令牌的所有用户

Posted

技术标签:

【中文标题】如何在 Node JS 中使用 jwt 授权具有不同令牌的所有用户【英文标题】:How to authorize all users with different tokens using jwt in Node JS 【发布时间】:2020-02-26 02:12:15 【问题描述】:

我有一个 node.js 应用程序。我正在使用 Json Web Token 进行授权。当我使用数据库中的用户登录时,它会为该用户创建一个令牌。但是我可以将该令牌用于另一个用户,并且它也可以再次使用。我需要为所有用户使用不同的令牌,并且我不应该将一个用户的令牌用于另一个用户。 (我的工作电脑上没有互联网,所以我不能在我的电脑上写我的代码,对此感到抱歉)

这是我的 verify-token.js(中间件):

const jwt = require("jsonwebtoken");

module.exports = (req, res, next) => 
  try 
    const token = req.headers.authorization.split(" ")[1];
    const decodedToken = jwt.verify(token, "secret_key");
    req.userData = decodedToken;
    next();
   catch (error) 
    return res.status(401).send(
      message: "Auth failed"
    );
  
;

这是我的登录代码(我在这里创建令牌) 如果密码为真:

const token = jwt.sign(
  
    email: user.email,
    password: user.password
  ,
  "secret_key",
  
    expiresIn: "2h"
  
);

return res.status(200).send( message: "success", token: token );

在 app.js 中:

const checkAuth = require('../middleware/checkauth');
router.get('/api/company',checkAuth,companyController.list);

我希望一个令牌应该只用于一个用户,并且对于每次登录它都应该为所有用户创建一个新令牌。有什么建议吗?

【问题讨论】:

你能再打开一下吗 【参考方案1】:

您将电子邮件包含在令牌正文中;为什么不将用户 ID 作为声明(字段)也包括在内?当您验证令牌时,如果成功,它会将正文返回给您,因此您将知道该令牌是为哪个用户制作的,如果不是发出请求的用户,则拒绝。

为确保两个人不会同时使用同一个令牌,您可以在生成每个有效令牌时,以及在令牌过期或被撤销时(例如,当用户退出或报告冒名顶替者,如果它走得那么远)将其从列表中删除。验证过程中,如果token不在列表中,不用解码,直接拒绝即可。

如果你给你的代币提供相当小的过期窗口(我相信建议是让它们持续不超过 1 小时),你不应该太担心这些事情。

编辑澄清一下,你永远无法确定给你令牌的人就是他们声称的那个人。您只知道您的服务器是否创建了令牌以及令牌当前是否有效。如果您真的想防止重放攻击(即绝对确保两个人无法同时使用同一个令牌),则每次使用一个令牌时都需要生成一个新令牌。如果您保留我上面提到的那个白名单,那么这种重新生成可以确保每个令牌在使用一次后立即失效。

为了更加自信,您还可以在令牌正文中包含 jti 声明;这是一个旨在在每次生成令牌时填充随机唯一值的字段,以便您可以跟踪您收到的 jti,并且不允许多次出现同一个。不过,这与仅跟踪令牌大致相同。

【讨论】:

reject if it's not the one who's making the request 你怎么知道是哪个用户发出了请求? 你没有。 Passport-JWT 甚至没有办法验证这一点(检查 Passport-JWT 的示例代码:他们只是检查有效负载中的用户是否存在于 Mongo 数据库中,如果存在,则认为它已验证。)无法知道发送令牌的人是他们声称的人;这是重放攻击的基础。最接近的选择是每次使用一个新令牌时都重新签署一个新令牌,而不仅仅是一个到期日期。我现在将其添加到答案中。 我的问题与 Passport-JWT 无关。但是我同意这一点。 对;我对你的问题的回答只是“你没有”。我只是继续谈论 Passport-JWT 来强调一点,即使是标准库也无法回答这个问题 :)

以上是关于如何在 Node JS 中使用 jwt 授权具有不同令牌的所有用户的主要内容,如果未能解决你的问题,请参考以下文章

如何实现身份验证和授权 WEB API 2 .NET 应用程序?尝试 JWT 库

Node.js学习笔记

在 Volley 请求中添加 JWT 令牌

node.js试图让护照和ExtraxtJwt工作

httpOnly cookie 中的 JWT - AuthGuard 和受保护的路由(Node.js、Angular)

如何在 Vuejs 和 Node 中设置授权标头并保护路由