首页 文章

React Native JWT还需要刷新令牌吗?

提问于
浏览
5

登录时,从服务器发送JWT访问令牌并保存在RN中的AsyncStorage中 .

现在我希望用户保持记录5年,直到他们:

  • 退出

  • admin撤销其令牌

  • 他们在3台设备上登录,在其中一台设备上更改密码,这些设备应将其从其他2台设备中注销,直到再次在这些设备上登录为止

  • 丢失手机,并从其他设备登录以从所有设备注销

看起来我必须在数据库中存储JWT令牌(我知道这不是JWT令牌的重点,并且根据我的阅读打败了他们服务的目的)但我需要知道用户的令牌,在他们的不同设备上,能够撤销它们 .

让我感到困惑的一件事就是读取访问令牌应该是短暂的,例如60分钟,刷新令牌长期存在,比如说我的情况是5年 .

我不明白为什么我们不能只使用访问令牌有5年的使用寿命(对于每个设备),将它们保存在数据库中的用户,以便我们可以识别他们的令牌并根据他们撤销他们的令牌上述几点?在这种情况下,甚至需要刷新令牌的重点是什么?

注意:我还读到我们无法撤销访问令牌,但只能撤销刷新令牌,所以我真的很困惑 . 我是否必须向RN发送访问令牌和刷新令牌,并且只使用授权承载头的刷新令牌并仅在DB中保存刷新令牌?那么访问令牌的重点是什么,如果它不是数据库中的那个?

我认为这应该是一个简单的实现,但我的标准是5年登录,并能够根据上述几点撤销令牌 .

对于这种情况,什么是正确的解决方案?

1 回答

  • 6

    访问令牌是短暂的,默认为24小时 . 但为什么?为什么不是5年?

    • 任何拥有访问令牌的人都可以保证访问用户(最初发布的用户)可以访问的任何内容 . 这意味着 the server cannot differentiate between that user and anyone else who has the access token .

    • There is NO logging out . 我在这里的意思是你可以让你的前端重定向到登录页面让他输入凭据,但真正注销不会在服务器中发生 . 从技术上讲,用户可以使用相同的访问令牌继续访问(直到它过期)

    • Access Tokens canNOT be revoked . 访问令牌仅在到期时失效 . 任何人都可以使用它,直到令牌过期 . 例如,如果到期时间设置为5年并且我偶然获得了您的令牌,那么我可以获得您拥有的所有访问权限,直到它到期为止,在这种情况下为5年 . 这正是更有意义地将到期时间设置为小于24小时 .

    现在让我们解决您的问题 . “我希望用户登录,直到他”

    • Logs out

    登录后向用户发送刷新令牌 . 非常安全地存储访问令牌和刷新令牌 . 在其访问令牌过期后,使用刷新令牌获取新的访问令牌 . 循环这直到他退出 . 当他注销时,删除前端的访问令牌和刷新令牌,并撤消服务器端的刷新令牌 . (再次,如果他以某种方式获得访问令牌,他仍然可以访问他的帐户,直到它到期)

    • Admin revokes token

    服务器不能像我之前所说的那样撤销访问令牌,一旦发布有效期到期满,无论如何 - >但只要用户拥有访问令牌:P打开应用程序后立即删除访问令牌,如果他在过去1小时左右没有持续打开应用程序 . 现在,前端被迫使用它存储的刷新令牌获取新的访问令牌 . 现在,您希望用户强制注销?撤消他的刷新令牌 .

    • Logout on all devices after password change

    更改密码后,撤销所有刷新令牌(如果您不希望用户再次登录,则撤销除当前设备之外的所有刷新令牌) . 您的所有设备上的应用程序都将被强制使用刷新令牌获取新的访问令牌,但由于您撤消了它,因此用户除了使用其凭据登录之外别无他法 .

    • User-triggered logout from all devices

    与更改密码触发所有设备上的注销,此处您只需添加“在所有设备上注销”按钮,该按钮将发送服务器请求,该请求将撤消除当前设备之外的所有刷新令牌 .

    Caveat :当前用户会话无法关闭;您需要等待用户退出应用程序,以便拥有当前访问令牌删除 . 解决方法是在关闭应用程序时立即删除访问令牌(甚至他最小化应用程序)或将访问令牌过期设置为30分钟,前提是您可以容忍每次使用刷新令牌获取新访问令牌所导致的延迟那样做 . 您需要权衡安全时间,反之亦然,具体取决于您的应用规范 .


    "That's all fine, but I don't want a refresh token in the first place" (替代解决方案):

    我不鼓励存储令牌,因为它通过增加由于查询数据库而增加的响应时间而破坏了扩展和阻止简单DDoS的目的 . 但是由于Redis是在内存上运行的速度非常快的键值存储,因此有些人更喜欢在其中存储访问令牌 . 那怎么办?

    设置:用户登录后,发出访问令牌 . 将其存储在Redis中,然后将其发送给用户 .

    • 检查JWT签名&&令牌的完整性,如果它失败了,没有数据库查询 . 发回404用户未找到 . 这将与没有Redis功能的JWT一样快 .

    • 如果成功,请检查Redis是否有令牌 . 如果存在,则授予访问权限 . 如果没有,请要求用户再次登录 . 请注意,这比使用JWT授予访问权限要慢一些,但是,嘿,你没有存储Postgres或Mongo,这可能需要几毫秒的时间来响应; Redis是一个键值存储 - 并且它位于内存(而不是存储)上 - 比这些快得多 .

    Access is granted if and only if both the conditions are satisfied: JWT is valid. JWT is present in Redis

    回答你的问题:

    现在可以退出 . 当用户点击注销时,从Redis中删除访问令牌 . 即使他有访问令牌,他也无法登录 . 访问令牌现在字面上无效 .

    • 管理员强制注销:从Redis删除该用户的访问令牌 .

    在用户成功授予服务器访问权限后,您应允许用户发出 request 以删除具有相同用户ID(或uid)的所有其他令牌,这将允许注销

    • 密码更改后,发出此类请求 .

    • 在从其他设备注销时,发出此类请求 .

    最后左边1.保持登录状态直到用户注销:既然您有权使用不使用Redis时没有的访问令牌无效,您可以拥有一个5年有效访问令牌,前提是您实现了其他要求防止滥用访问令牌的安全措施 .

相关问题