免责声明,我是JWT的新手,所以如果其中任何一个根本没有意义,你现在知道为什么哈哈。
动机 此实现可以解决此实现试图解决的安全问题:
Legit用户使用公共计算机登录网站并离开该地点忘记退出,攻击者坐在该计算机上,复制粘贴令牌并在他回家后随时随地使用它(因为它始终有效直到秘密更改或者您正在将数据库存储在数据库中,直到用户更改某些有效负载信息[如果用户永远不会更新信息],那么令牌永远有效。)
对上述问题进行排序的身份验证流程
1. Client logs in
1.1 Verify login details, and if valid:
1.2 Create token using user id, global secret and expiry date
1.3 Store token in Database
1.4 Send token to client
2. Client stores token [your choice where u wanna store it]
3. When client sends a request to an authenticated route, use authentication middleware to do the following checks
3.1 Verify token hasn’t been tampered with
3.1.1 If not tampered, go to 3.2
3.1.2 If tampered, redirect to /login
3.2 check if expiration date is less than current date
3.2.1 if not less, let user through to the requested route, by calling next()
3.2.2 if less, check in database if expired token matches the token stored in database
(to verify if it’s the latest expired token, or not)
3.2.2.1 if doesn’t match, redirect to /login
3.2.2.2 If matches
3.2.2.2.1 create token with renewed expiration date
3.2.2.2.2 store token in database
3.2.2.2.3 send token to client
以上实施的安全缺陷 如果攻击者获得了对令牌的访问权限,并且是在令牌到期后第一个请求获得新令牌的那个令牌,那么当他们试图获取新令牌并将其注销时,这将使合法用户无效因为他们的令牌与存储在数据库中的令牌不匹配。现在只有攻击者拥有与数据库中存储的令牌相同的令牌。
缓解此问题的方法 通过登录或注销无效:在注销时在登录/删除令牌上生成新令牌,覆盖db中的旧令牌,这将使所有先前发出的令牌一旦过期就无效。即下一次攻击者试图在到期时获取新令牌,它将与db中的一个不匹配,因此他们将永远使用该令牌被拒绝。
可用性问题 登录或注销会使所有其他设备上的令牌无效,因此您必须在这些设备上重新登录。
可能的解决方法 对设备类型进行简单的请求标头检查,并在登录和注销时为每个设备存储不同的令牌。然后在需要刷新令牌时根据不同设备的if语句进行不同的db查询,因此你知道要刷新哪一个。
答案 0 :(得分:2)
1.3在数据库中存储令牌
没有必要,不推荐。验证JWT的签名是JWT有效的证明。保存令牌需要在每个请求中使用不必要的存储空间和数据库访问
Legit用户使用公共计算机登录网站并离开该地点忘记退出,攻击者坐在该计算机上,复制粘贴令牌并在他回家后随时随地使用它。
此安全问题是可能的,但认为攻击风险较低且受影响的用户数量不会很高,因为它需要在使用您的网站后对共享计算机进行物理访问。预防和缓解措施应与问题的严重性相称。
您建议在真实用户的新登录/注销时使旧令牌无效,但用户未注销,因此不会降低风险。服务器不知道是否令牌来自真实用户或来自攻击者。拥有JWT是身份验证的证明。
我建议采取以下预防措施:
过期时间短:每3-5分钟续订一次令牌
使用会话存储空间而不是cookies / localStorage:浏览器关闭时会清除会话存储空间。
如果此操作不够,请考虑申请登录凭据而不是存储JWT。
其余要点基于将JWT存储在数据库中。正如我在上面评论的那样,使用JWT
是没有意义的可用性问题登录或注销会使所有其他设备上的令牌无效,因此您必须在这些设备上重新登录。
为每个设备发出新令牌。建议让令牌过期,但如果您需要使令牌无效,则可以在JWT中使用包含唯一标识符jti
的黑名单。
答案 1 :(得分:0)
我认为它看起来很不错,尽管pedrofb commensta是有效的。但是,请考虑不将JWT本身存储在数据库中,而是将刷新令牌存储在数据库中。刷新令牌不是JWT,它只是一个随机数,时间戳或类似的,刷新令牌嵌入在JWT中。
还要考虑在JWT上添加软到期。软到期是您的专有到期日。只要标准的到期日期未通过,JWT就有效,但在软到期后,您希望将JWT中的刷新令牌验证为存储在数据库中的一次。这将是实际验证用户对数据库的频率的心跳。另一方面,标准到期日是用户需要至少与您的BE交互一次以发布新的JWT(具有新的到期日期)的日期。因此,有效期可能是3个月,5分钟后软到期。
如果用户退出,如果检测到奇怪的行为,则更改PW och,您可以使DB中的刷新令牌无效。每次出现新的JWT时,您也可以更改刷新令牌,以防止更新旧的JWT。此外,您可以为用户登录的每个设备存储单独的刷新令牌,就像您为原始提案计划的那样。 (这允许用户从单个用户登出,监控用户登录的设备并远程登出设备。)