Geo*_*rds 11 node.js jwt typescript passport.js json-web-token
我有一个带角度前端的nodejs api.API成功地使用JWT和护照来保护它的端点.
我现在意识到,在令牌过期后,我的前端仍然允许用户请求我的api端点,而不会提示他们重新输入他们的登录详细信息以获得新的令牌.
这是我的后端生成令牌的方式:
function generateToken(user) {
return jwt.sign(user, secret, {
expiresIn: 10080 // in seconds
});
}
Run Code Online (Sandbox Code Playgroud)
因此,要实现此逻辑,我认为我需要验证JWT令牌客户端.Q1,这是一种明智的做法.
Q2,JWT我使用的库似乎需要一个公钥来使用它的verify()功能.我似乎没有公钥,只有一个秘密,我刚刚组成,所以它不是用一对产生的.我的公钥来自哪里,或者有没有其他方法来验证我的令牌?
这一切似乎都应该是显而易见的,我已经错过了一些东西,如果这是一个愚蠢的问题,请道歉,但我似乎无法找到答案?
gab*_*ssi 22
TL; DR
我现在意识到,在令牌过期后,我的前端仍然允许用户请求我的api端点[...]
因此,要实现此逻辑,我认为我需要验证JWT令牌客户端
如果我理解正确,那么你正在讨论检查JWS是否已在客户端过期.为了做到这一点,您不需要验证令牌签名(尽管您使用的库似乎同时为您执行这两项操作,但也允许您使用ignoreExpiration标志禁用到期控制).(除非您正在加密声明,即使用JWE)RFC 7515(JWS)没有说明过期.消息签名或MAC验证不控制到期(并且不应该因为签名为您提供真实性和完整性).如果JWT 有效,即使RFC 7519(JWT)也不控制解决的到期声明.
此外,所有索赔都是可选的.
因此,您可以在不验证签名的情况下检查JWT是否已过期,因此您既不需要公钥(对于非对称加密,如RSA),也不需要密钥(对于AES等对称加密).在JWT和JWS令牌中,声明只是明文base64编码,因此您可以解码有效负载,而无需验证签名是否有效并读取到期声明.如果您正在加密有效负载(也就是使用JWE),那么您将无法执行此操作.
来自jjwt库的说明
JWT可以加密签名(使其成为JWS)或加密(使其成为JWE).
这是来自auth0的ligthweigth库,用于解码JWT/JWS令牌的base64encoded声明.一个人甚至询问检查过期.
我不知道为什么你认为你应该做这个控制客户端,唯一的好处是避免发送客户端知道会失败的API请求.它们应该失败,因为服务器应该验证令牌未过期,以前的签名验证(使用秘密/私钥).
在RFC 7519说,这个要求:
"exp"(到期时间)声明标识JWT 不得接受处理的时间或之后的到期时间.
在像您所说的那样的Web应用程序中,使用令牌是允许无状态服务器对客户端请求进行身份验证.可选的到期声明的目标是允许服务器对生成的JWS进行一些控制(如果我们使用JWT进行身份验证签名,那么我们应该讨论JWS).
如果没有过期,令牌将永久有效或直到用于签名的密钥发生更改(这将使验证过程失败).顺便说一句,使 会话无效是使用无状态身份验证的最臭名昭着的缺点之一.
如果我们在用于授权的JWS有效负载(也称为声明)中包含信息(例如用户具有哪些角色),则会话失效成为真正的问题.
但更严重的是,它也可能意味着有人拥有一个具有管理员角色的令牌,即使你刚刚撤销了他们的管理员角色.由于您也无法使令牌无效,因此您无法删除其管理员权限
到期控制不能解决这个问题,我认为更倾向于避免会话劫持或CSRF攻击.
使用CSRF的攻击者将能够使用过期的JWS向您的API发出请求,跳过到期控制.
另一个问题是使用公钥或密钥验证客户端中的签名.
关于你的问题
我使用似乎需要一个公钥来使用它的verify()函数.我似乎没有公钥,只有一个秘密,我刚刚组成,所以它不是用一对产生的.
您指出的验证方法明确表示它接受公钥或密钥.
jwt.verify(token, secretOrPublicKey, [options, callback])
Run Code Online (Sandbox Code Playgroud)
secretOrPublicKey是一个字符串或缓冲区,包含HMAC算法的秘密,或者包含RSA和ECDSA的PEM编码公钥
我假设你没有使用,你使用像'shhhh'这样的字符串.
var token = jwt.sign({ data: '¿Donde esta Santiago?'}, 'shhhh');
Run Code Online (Sandbox Code Playgroud)
那你应该这样做
var decoded = jwt.verify(token, 'shhhhh');
Run Code Online (Sandbox Code Playgroud)
但是,这里的问题是:真的需要客户端签名验证吗?
我认为不是,至少不是这种应用程序,客户端只是使用JWS向服务器发送后续请求说:"嘿服务器,我是Gabriel,我在这里有纸(令牌)确保和那篇论文是你签名的." 因此,如果客户端未验证JWS并且MITM已成功向该客户端提供由他自己签名的JWS(而不是由服务器签名的JWS),则后续请求将失败.与过期控制一样,签名验证仅阻止客户端发出失败的请求.
现在,客户端验证需要发送公钥或密钥.发送公钥并不代表安全问题,但是额外的工作和处理几乎没有任何好处.
发送密钥(如"shhhh")可能代表安全问题,因为它与用于签署令牌的密钥相同.
| 归档时间: |
|
| 查看次数: |
14658 次 |
| 最近记录: |