如何在 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 库