Ruby on rails 使用JWT和刷新令牌验证移动应用程序

Ruby on rails 使用JWT和刷新令牌验证移动应用程序,ruby-on-rails,authentication,oauth-2.0,jwt,json-web-token,Ruby On Rails,Authentication,Oauth 2.0,Jwt,Json Web Token,现在我开始对这件事大发雷霆。在过去的几天里,我做了一些研究,似乎不太明白如何实现以下目标: 我目前正在Rails中构建一个API,客户端是一个移动应用程序。移动应用程序可以是iOS或Android。现在,我正在努力进行身份验证。在客户机登录到设备后,我会发出一个JWT,它的有效期很短。因此,如果令牌过期,客户端需要重新登录,这在我的情况下是不可接受的。无论如何,我觉得我需要有某种到期日,以防止令牌被偷走后永远被使用 现在我想知道如何集成刷新令牌。如何确保用户只能使用已颁发给该设备的有效刷新令牌获

现在我开始对这件事大发雷霆。在过去的几天里,我做了一些研究,似乎不太明白如何实现以下目标:

我目前正在Rails中构建一个API,客户端是一个移动应用程序。移动应用程序可以是iOS或Android。现在,我正在努力进行身份验证。在客户机登录到设备后,我会发出一个JWT,它的有效期很短。因此,如果令牌过期,客户端需要重新登录,这在我的情况下是不可接受的。无论如何,我觉得我需要有某种到期日,以防止令牌被偷走后永远被使用

现在我想知道如何集成刷新令牌。如何确保用户只能使用已颁发给该设备的有效刷新令牌获取新的访问令牌?或者,我是否将事情过度复杂化,并分配一个可以在所有设备上使用的刷新令牌,这将起到作用

更新:我查看了门卫宝石,它支持密码授予流程。但doorkeeper处理令牌的方式是,它将生成的每个访问令牌与相应的刷新令牌存储在数据库中。当令牌被撤销或刷新时,旧的访问令牌将失效——随着时间的推移,这将成为一个巨大的数据库表

此外,我更喜欢使用JWT作为令牌,因此除了刷新令牌之外,我不必在数据库中存储任何东西。以下过程是否安全

  • 用户请求使用用户名/密码和设备名称访问令牌
  • 服务器发出JWT并为当前设备创建刷新令牌
  • 服务器存储刷新令牌
  • 当访问令牌过期时,用户使用其刷新令牌请求一个新的令牌
  • 服务器验证刷新令牌并发出新的访问令牌。此外,刷新令牌将被替换为新令牌

  • 我的问题是:用户可以登录多个设备,如何区分它们

    我看到的工作方式是,服务器返回一个未经授权的状态(401),并显示一条消息,指示访问令牌已过期,但客户端只有一次机会使用该过期令牌请求新令牌。一旦客户端使用该过期令牌请求一个新的令牌,过期令牌将变得无效,并且不能再使用。这样你就可以继续用旧的代币换新的

    如果您的过期时间很短,那么被盗令牌仍然有效的可能性很小,但是从用户体验的角度来看,用户将保持登录状态,因为令牌协商可能只是在后台进行的。只有当用户注销或他们使用的令牌在服务器端显式失效时,用户的令牌才会失效


    对于您拥有的每个用户名/密码组合,您肯定也应该有一个唯一的令牌。为应用程序中的每个客户端使用相同的令牌是非常不安全的。

    我喜欢刷新令牌的想法。在后端,如何使用?这样,令牌到期时间会在每个客户端请求时更新

    用户使用用户名/密码请求访问令牌,比如 设备名称

    向服务器发送用户名/密码和设备名称将无法实现客户端不必向您提供凭据的目的


    我将其视为移动客户端从oauth提供商请求令牌id(您需要一个服务器clientID)。移动客户端将令牌id发送到服务器进行验证,从而确保客户端身份。服务器可以在成功验证提供的JWT中找到用户的电子邮件地址。请参阅rails gem。

    安全性始终是相对的,通过更多的努力,我们可以让任何人更难滥用系统。承载令牌是IO绑定的(缓存/数据库调用),JWT令牌是CPU绑定的(加密/解密)。这两个都是常规服务领域中足够好的解决方案,除了我们在这里介绍的关于移动设备的一件事。这里可以使用的方法之一是通过反向通道将令牌/刷新令牌发送到设备,而不是将其作为身份验证的一部分发送。看起来有些额外的工作,但在为移动设备颁发和刷新代币方面提供了更多的安全性。更多细节可以在这里找到

    实际上,我不太喜欢只有一个访问令牌而没有刷新令牌的想法。因此,潜在的攻击者可以使用被盗的访问令牌生成无限的新令牌。此外,我希望尽可能接近OAuth2规范。请查看我的更新问题。我想使用JWT,使用doorkeeper+JWT将最终在数据库中存储JWT令牌-无论如何,JWT应该是独立于数据库的,因此将它们存储在db中没有任何意义。堆栈溢出有一个漏洞,我知道您的网站与您的用户名匹配,但我建议您明确连接。例如,您可以在链接旁边添加短语“我的网站”。