TL;DR
- 您必须在server always中填写JWS的签名.
- Client-side signature verification不会给你带来太多,除非你有一个具体的例子,说明它是有意义的don't do it.
- 你的客户是don't need to verify the signature of a JWS token to check expiration人.(除非你加密声明,也就是使用JWE,在这种情况下,你需要做类似的事情,因为你需要一个密钥来解密声明).
- 您也不需要验证JWS的签名来判断服务器中的过期情况,但您应该这样做,因为这可以确保没有人更改过期情况(否则验证将失败,因为如果声明发生更改,则重新计算的签名将不同)
- 要阅读未加密的声明,只需解码即可.你可以在客户端使用jwt-decode.
我现在意识到,在令牌过期之后,我的前端仍将允许用户请求我的api端点[…]
所以为了实现这个逻辑,我想我需要在客户端验证JWT令牌
如果我没弄错的话,你说的是判断客户端的JWS是否过期.
还有,所有的claims are optional人.
因此,您可以在不验证签名的情况下判断JWT是否过期,因此您既不需要公钥(对于RSA等非对称加密),也不需要密钥(对于AES等对称加密).
jjwt library美元的钞票
JWT可以是加密的signed(JWS)或encrypted(JWE).
Here是ligthweigth library from auth0 to decode the base64encoded claims of a JWT/JWS token.
我不知道您为什么认为应该在客户端执行此控制,唯一的优点是避免发送客户端知道会失败的API请求.它们应该会失败,因为服务器应该验证令牌没有过期,之前的签名验证(使用秘密/私钥)显然是无效的.
RFC 7519人对这一说法表示:
"exp"(过期时间)声明标识
在像您所说的那样的web应用中,令牌的使用是为了允许无状态服务器对客户端请求进行身份验证.
如果没有过期,令牌将永远有效,或者直到用于签名的密钥更改(这将导致验证过程失败).
如果我们在用于授权的JWS有效负载(又名声明)中包含信息,例如用户拥有哪些角色,那么会话失效就会成为一个真正的问题.
从Stop using JWT for sessions
但更严重的是,这也可能意味着某人拥有一个具有管理员角色的令牌,即使你刚刚撤销了他们的管理员角色.因为您也不能使令牌无效,所以您无法删除它们的管理员访问权限
过期控制并不能解决这个问题,我认为它更倾向于避免会话劫持或CSRF攻击.
使用CSRF的攻击者将能够使用过期的JWS向API发出请求,从而跳过过期控制.
使用公钥验证客户机中的签名或密钥是不同的问题.
关于你的问题
我正在使用的函数似乎需要公钥才能使用它的verify()函数.我似乎没有公钥,只有一个秘密,这是我编造的,所以它不是用一对密钥生成的.
您指出的验证方法明确表示它接受公钥或密钥.
jwt.verify(token, secretOrPublicKey, [options, callback])
secretOrPublicKey是一个字符串或缓冲区,其中包含HMAC算法的密钥,或者包含RSA和ECDSA的PEM编码公钥
我假设你两个都不使用,而且你使用的是像"shhh"这样的字符串.
var token = jwt.sign({ data: '¿Donde esta Santiago?'}, 'shhhh');
那你应该这么做
var decoded = jwt.verify(token, 'shhhhh');
然而,这里的问题是:真的需要客户端签名验证吗?
我认为不是,至少不是针对这种应用程序,客户机只是使用JWS向服务器发送后续请求,并说:"嘿,服务器,我是Gabriel,我这里有一份文件(令牌),可以确保该文件由您签名."
现在,客户端验证需要发送公钥或密钥.
发送密钥(如"shhhh")可能代表一个安全问题,因为密钥与用于签名令牌的密钥相同.