我正在使用JWT来保护节点js urls https://github.com/auth0/express-jwt
要创建JWT令牌用户会话,我只需执行以下操作:
-> auth/signup
-> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
如果是登录电话,则为
-> auth/login
-> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
每次调用受保护的URL时,我都会检查由JWT中间件自动设置的req.user
。
现在我想知道:
1 - 调用sign()时,JWT令牌存储在哪里?
2 - 每次调用受保护的URL时,我是否必须验证()令牌?如果是的话为什么?
3 - 当我为已经签名的用户设置新令牌时,旧令牌(如果存在)会被删除吗?如果未设置到期或例如5年,该怎么办?
4 - 为什么我不能在同一浏览器/应用页面上设置新令牌? 如果我注册一个新令牌但令牌匹配(我已选中),我会收到无效的签名错误 这就像我不能在同一个浏览器上签署多个用户
答案 0 :(得分:17)
您必须已经使用之前其他用户的回复找出了之前所有问题的答案,但我也会尝试为其他用户清除一些问题:
1 - 调用sign()时,JWT令牌存储在哪里?
当您呼叫签名时,签名的令牌不会存储在任何地方,它是 通过sign函数返回,然后你必须将它发送给客户端 这样就可以存储在客户端。 (例如会话存储, 本地存储或cookie)
2 - 每次调用受保护的URL时,我是否必须验证()令牌?如果是的话为什么?
是的,你这样做。这个想法是,一旦客户端拥有令牌,他们就会发送令牌 每次发出请求时,令牌都会发送到服务器。令牌是 由服务器处理以确定特定客户端是否具有 已经过验证。
3 - 当我为已经签名的用户设置新令牌时,旧令牌(如果存在)会被删除吗?如果未设置到期或例如5年,该怎么办?
与第1点的答案略有关联。调用符号功能 只会生成另一个令牌。令牌的到期时间是 存储在签名的令牌本身中。所以每次服务器获得一个令牌 从客户端,它将到期作为令牌的一部分进行检查 验证。重要的是要注意签名的令牌只是 在此期间作为参数传入的“user_profile”对象 签名,加上额外的字段,例如添加到的截止日期 那个对象。
因此客户端可以在客户端存储多个令牌。他们 只要它们尚未过期,它们都将有效。然而 想法是只在它们出现时才向客户发送令牌 旧版本过期后再次验证。
4 - 为什么我无法在同一浏览器/应用页面上设置新令牌?如果我注册一个新令牌但令牌匹配(我检查),我得到无效的签名错误就像我不能在同一个浏览器上签署多个用户
这个想法是每个浏览器有1个用户。因为在这种情况下是浏览器 是客户。我想不出你需要的用例 每个浏览器/客户端有多个用户,所以你显然在做 有问题。这并不是说不可能发送多个 令牌到同一个浏览器/客户端。
答案 1 :(得分:8)
您需要将令牌存储在客户端(本地存储或cookie)
是。 HTTP是无状态的。如果您不是每次都进行验证,则有人可以在没有令牌或无效令牌的情况下调用您的URL。如果您担心性能,HMACSHA256检查速度非常快。
这没有意义,你必须做错事。
答案 2 :(得分:3)
2 - 每次受保护的网址都必须验证()令牌 叫什么名字?如果是的话为什么?
是。但是"验证"是一个有点混乱的术语。
在令牌验证期间,不需要对用户凭据进行数据库检查,因为服务器必须信任已接收和验证(成功解密)的令牌。无需服务器会话存储来识别用户。
您可以将JWT令牌视为简单的会话信息,以加密形式存储在客户端上。但是,如果您需要在用户会话信息中缓存更多数据,我认为,您仍然需要在服务器上存储某种会话存储,与Cookie中的传统会话ID相比,JWT的想法几乎无用。
答案 3 :(得分:2)
对不起。这应该是对先前答案的评论,但我没有足够的代表评论,所以他去了
@sbaang:每次验证的另一个原因是令牌中可能存在有趣的" claim2,例如允许用户访问某些端点,而不是所有端点。因此,在每次验证中,您不仅要验证用户是否被允许访问受保护的API,还要检查该特定端点,而不是基于拥有有效令牌,而是拥有专门允许该令牌的令牌。