JWT注销功能不使用黑名单?

JWT注销功能不使用黑名单?,jwt,logout,Jwt,Logout,我以前使用过JWT,但它们是API,不需要注销功能 我需要为android应用程序的API和SPA实现注销功能。我查了一下,发现有两种方法 最简单的方法是从客户端删除JWT令牌,然后结束 这背后的逻辑是,由于服务器中没有维护任何类型的会话,所以在客户端删除令牌就足够了。 但是,如果令牌落入坏人之手,即使用户不再使用令牌,他们仍然可以使用它 如果应用程序设计良好,并且使用了HTTPS,那么发生这种情况的可能性很低,可以通过缩短令牌的有效时间来最小化。但就我而言,代币的有效期为30天 第二个选项是在

我以前使用过
JWT
,但它们是
API
,不需要注销功能

我需要为android应用程序的
API
SPA
实现注销功能。我查了一下,发现有两种方法

  • 最简单的方法是从客户端删除
    JWT令牌
    ,然后结束 这背后的逻辑是,由于服务器中没有维护任何类型的会话,所以在客户端删除令牌就足够了。 但是,如果令牌落入坏人之手,即使用户不再使用令牌,他们仍然可以使用它

    如果应用程序设计良好,并且使用了
    HTTPS
    ,那么发生这种情况的可能性很低,可以通过缩短令牌的有效时间来最小化。但就我而言,代币的有效期为30天

  • 第二个选项是在服务器端维护令牌黑名单
  • 这解决了即使在用户注销并停止使用令牌后,令牌仍然可用的问题

    但它增加了一个复杂性,即需要运行
    cronjob
    从黑名单表中删除过期的令牌。否则,桌子最终会变得大得离谱

    它也有点违背了使用JWT的观点。维护黑名单与维护会话非常相似。我们必须为每个请求运行额外的db查询。而且它的扩展性很差,随着用户数量的增长,需要被列入黑名单的令牌数量也会增加(这对于像我这样的
    API
    来说将是一个更大的问题,因为它有多个前端应用程序,令牌的有效期很长)

    然后我想到了第三条路

    在存储随机生成字符串的用户表中添加
    jwt_secret
    行。使用它对
    JWT令牌进行签名
    ,然后在每次请求时,在
    JWT有效载荷
    中使用
    user id
    获取用户表单db(这不是额外的查询,我们无论如何都必须这样做),并使用用户的
    JWT_secret
    验证令牌签名。当用户注销时,我们更改了
    jwt_secret
    ,这使得所有的令牌都无用

    起初,我认为这是一个很好的解决方案,但后来我意识到,在这个设置中,如果用户从一个设备或浏览器注销,他/她将从所有设备注销


    那么还有其他选择吗?或者通过修改上述任何一种方法来解决问题。还是我考虑过了,应该使用上面的选项之一?

    用于注销,正如您指出的,这是用户发起的操作,我认为您不需要做任何额外的事情。如果用户不知何故没有删除他的JWT,那么就这样吧。他将不会获得任何额外的访问权来访问他已经有权访问的内容

    然而,您的问题似乎暗示了如何知道JWT是否有效的问题。再次,正如你所指出的,如果JWT不知何故落入了坏人之手,那么可能无法避免这一点。但是,对于每个请求,您通常会针对该JWT执行几种类型的验证,例如

    • 检查JWT的声明,例如令牌到期日
    • 假设索赔通过,然后根据数据库表检查该用户的ID,以确保该帐户处于活动状态,未被挂起,等等

    我的观点是,如果您需要在服务器端跟踪发生的注销,您可能需要将其持久化到数据库。但是,我认为您不需要这样做。

    对于注销,正如您指出的,这是用户发起的操作,我认为您不需要做任何额外的事情。如果用户不知何故没有删除他的JWT,那么就这样吧。他将不会获得任何额外的访问权来访问他已经有权访问的内容

    然而,您的问题似乎暗示了如何知道JWT是否有效的问题。再次,正如你所指出的,如果JWT不知何故落入了坏人之手,那么可能无法避免这一点。但是,对于每个请求,您通常会针对该JWT执行几种类型的验证,例如

    • 检查JWT的声明,例如令牌到期日
    • 假设索赔通过,然后根据数据库表检查该用户的ID,以确保该帐户处于活动状态,未被挂起,等等

    我的观点是,如果您需要在服务器端跟踪发生的注销,您可能需要将其持久化到数据库。但是,我认为您不需要这个。

    谢谢您的回复。我也得出了同样的结论,只是想听听第二个意见。你应该使用每个用户(存储)的秘密,你可以删除它,使所有基于旧秘密的JWT令牌无效。谢谢你的回复。我也得出了同样的结论,只是想听听第二种意见。你应该使用每个用户(存储)的秘密,你可以删除它,根据旧的秘密使所有JWT令牌失效。你可以使用JWT中的
    aud
    jti
    声明向每个设备发出单独的JWT令牌,然后根据
    aud
    id,您只能使一个客户端的会话无效。这要求您唯一地标识一个客户机,或者始终发出新的
    aud
    ,这将使数据库混乱并减慢索赔验证,或者定期清理长期未使用的会话表。。。如果您将这一点与每用户机密结合起来,您必须选择使一个或所有客户端失效(注销与注销所有设备),您可以使用JWT中的
    aud
    jti
    声明向每个设备发出单独的JWT令牌,然后根据
    aud
    id,您只能使一个客户端的会话失效。这要求您唯一地标识一个客户机,或者始终发出新的
    aud
    ,这将使数据库混乱并减慢索赔验证,或者定期清理长期未使用的会话表。。。如果你结合