gpt4 book ai didi

node.js - JWT 验证客户端?

转载 作者:IT老高 更新时间:2023-10-28 23:23:28 30 4
gpt4 key购买 nike

我有一个带有角度前端的 nodejs api。 API 成功地使用 JWT 和 Passport 来保护它的端点。

我现在意识到,在 token 过期后,我的前端仍将允许用户请求我的 api 端点,而不会提示他们重新输入登录详细信息以获取新 token 。

这是我的后端生成 token 的方式:

function generateToken(user) {
return jwt.sign(user, secret, {
expiresIn: 10080 // in seconds
});
}

所以为了实现这个逻辑,我想我需要验证 JWT token 客户端。 Q1,这是一个明智的方法。

Q2, JWT 我正在使用的库似乎需要公钥才能使用它的 verify()功能。我似乎没有公钥,只有一个我刚刚编造的 secret ,所以它不是用一对生成的。我的公钥来自哪里,或者有没有其他方法可以在没有这个的情况下验证我的 token ?

这一切似乎都应该是显而易见的,而且我错过了一些东西,如果这是一个愚蠢的问题,我很抱歉,但我似乎找不到答案?

最佳答案

TL;博士

  • 您必须验证 JWS 在 中的签名服务器总是 .
  • 客户端签名验证不会给出太多,除非您有一个有意义的特定案例 不要这样做 .
  • 不需要验证 JWS token 的签名来检查过期 在客户端。 (除非您正在加密声明,也就是使用 JWE,在这种情况下您需要做类似的事情,因为您需要一个 key 来解密声明)。
  • 您不需要验证 JWS 的签名来检查服务器中的过期时间,但您应该这样做,因为这可以让您确定没有人更改过期时间(否则验证将失败,因为如果声明更改,则重新计算签名会有所不同)
  • 要阅读非加密声明,您只需要对其进行解码。您可以使用 jwt-decode在客户端。

  • I am now conscious that after the tokens have expired, my front end will still allow the user to request my api endpoints [...]

    So to implement this logic I think I need to verify the JWT token client-side



    如果我理解正确,您正在谈论检查 JWS 是否在客户端过期。
    为此,您不需要验证 token 签名(尽管您使用的库似乎在为您执行 both things at the same time,但也允许您使用 ignoreExpiration 标志禁用过期控制)。 (除非您对声明进行加密,也就是使用 JWE)
    RFC 7515 (JWS)什么都没说到期。 Message Signature or MAC Validation不控制过期(它不应该控制,因为签名为您提供真实性和完整性)。
    甚至 RFC 7519 (JWT)如果 JWT is valid or not,则不控制解决的到期声明.

    另外,所有 claims are optional .

    因此,您可以在不验证签名的情况下检查 JWT 是否已过期,因此您既不需要公钥(对于 RSA 之类的非对称加密),也不需要 key (对于 AES 之类的对称加密)。
    在 JWT 和 JWS token 中,声明只是纯文本 base64 编码,因此您可以仅 decode the payload without verifying if the signature is valid并阅读过期声明。
    如果您正在加密有效负载(也就是使用 JWE),那么您将无法执行此操作。

    来自 jjwt library 的注释

    JWTs can be cryptographically signed (making it a JWS) or encrypted (making it a JWE).



    Here来自 auth0 的 ligthweigth 库,用于解码 JWT/JWS token 的 base64 编码声明 .
    一个人甚至在问 checking expiration .

    我不知道你为什么认为你应该在客户端做这个控制,唯一的好处是避免发送客户端知道会失败的 API 请求。并且它们应该失败,因为服务器应该验证 token 尚未过期,显然先前的签名验证(使用 secret /私钥)。

    RFC 7519说到这个说法:

    The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing.



    在像您所说的那样的 Web 应用程序中,使用 token 是为了允许无状态服务器对客户端请求进行身份验证。
    的目标可选 过期声明是为了允许服务器对生成的 JWS 有一些控制(如果我们使用 JWT 进行身份验证,则必须对它们进行签名,所以我们应该谈论 JWS)。

    如果没有到期, token 将永远有效或直到用于签署它们的 key 发生变化(这将使验证过程失败)。
    顺便说一句, invalidating sessions是使用无状态身份验证最臭名昭著的缺点之一。

    如果我们在用于授权的 JWS 负载(又名声明)中包含信息,例如用户具有哪些角色, session 失效就会成为一个真正的问题。

    来自 Stop using JWT for sessions

    but more seriously, it can also mean somebody has a token with a role of admin, even though you've just revoked their admin role. Because you can't invalidate tokens either, there's no way for you to remove their administrator access



    过期控制并没有解决这个问题,我认为更倾向于避免 session 劫持或 CSRF 攻击。

    使用 CSRF 的攻击者将能够使用过期的 JWS 向您的 API 发出请求,跳过过期控制。

    另一个问题是使用公钥或私钥验证客户端中的签名。

    关于你的问题

    I am using seems to require a public key to use it's verify() function. I don't seem to have a public key, only a secret, which I just made up, so it wasn't generated with a pair.



    您指出的验证方法明确表示它接受公钥或私钥。
    jwt.verify(token, secretOrPublicKey, [options, callback])

    secretOrPublicKey is a string or buffer containing either the secret for HMAC algorithms, or the PEM encoded public key for RSA and ECDSA



    我假设您既不使用,又使用像“shhhh”这样的字符串。
    var token = jwt.sign({ data: '¿Donde esta Santiago?'}, 'shhhh');

    那你应该做
    var decoded = jwt.verify(token, 'shhhhh');

    然而,这里的问题是:真的需要客户端签名验证吗?

    我认为不是,至少对于这种客户端仅使用 JWS 向服务器发送后续请求的应用程序来说不是这样:“嘿,服务器,我是 Gabriel,我在这里有一张纸( token ),可以确保和那张纸是你签字的。”
    因此,如果客户端不验证 JWS 并且 MITM 已成功向该客户端提供了一个由他自己签名的 JWS(而不是由服务器签名的 JWS),那么后续请求将简单地失败。
    与过期控制一样,签名验证仅防止客户端发出将失败的请求。

    现在,客户端验证需要发送公钥或私钥。
    发送公钥并不代表安全问题,但它是额外的努力和处理,几乎没有好处。

    发送 key (如“shhhh”)可能代表安全问题,因为用于签署 token 的 key 相同。

    关于node.js - JWT 验证客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43788131/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com