运行"普通"的最佳方法在任何其他REST调用之前调用REST

时间:2017-04-04 03:56:17

标签: android rest jersey retrofit jwt

我有一个使用JWT保护的REST API。客户端是Android应用程序和Web应用程序。当用户登录时,Android应用会获得一个新令牌,之后它会使用该令牌。但是令牌将在60分钟后到期,所以我必须刷新它。我知道有3种方法。

  • 在每个请求中发出一个新令牌
  • 在当前的令牌即将到期时发出新令牌。例如10 分钟
  • 让客户端应用在需要时使用"刷新请求新令牌 服务"你的api。

请考虑以下内容......

  • 我对上面的第一个建议不满意
  • 我确实尝试了第三个建议。但是在我的Android应用程序中,我得到了60个REST调用。然后我应该做的是每次REST调用(例如:getUsers()),我首先要检查令牌是否即将过期,如果是,则从REST API获取一个新令牌(这意味着我必须对API中的refresh()方法运行另一个REST调用。在检查并获取新令牌之后,我可以执行getUsers()方法。这里的问题是每个REST调用应该在我的onResponse()方法的refresh()方法内运行(我正在使用Retrofit),这是不可能的,因为我必须复制相同的方法60次有60个名字。我确信网络应用程序也会出现同样的问题。

由于上述原因,我正在考虑我的第一个列表中的第二个建议,在服务器上更新令牌。如果令牌是"有效"如果它即将到期"我将从服务器刷新它,并将作为标题发送到应用程序。

我需要知道这种方法是否是一种行业实践方法,而且它是最佳选择。如果没有,我如何在第一个清单中继续提出第三个建议。

1 个答案:

答案 0 :(得分:0)

我最近在我的一个Android应用中使用JWT实现了类似的设置。我不知道我的建议是否会对您有所帮助,但它可能会让您了解其他人是如何做到的。

选项1:这非常多余,并且它首先违反了使用JWT的唯一目的。如果我在每个请求中获得一个新的JWT,我可以将其用于进一步的请求,因此实际上有一个没有过期的令牌。

选项2:这需要服务器端额外操作,这是不可行的。您打算如何检测哪些令牌已经分发并且即将到期"这样你可以更新它们吗?大量用户将拥有大量令牌,如果您计划将JWT保存在数据库中,那么它将变得太乱。

选项3:此方法过于简化,需要客户端操作检查令牌是否即将过期并根据该方法调用刷新服务。我总是喜欢较少的操作来做更多的工作。

我做了什么,是,我为系统使用了两个令牌。一个用作刷新令牌 (用于请求JWT刷新的令牌),一个用作 JWT (用于每个请求验证)

成功登录后,收到刷新令牌并将其保存在app (SharedPref)中。此令牌也会保留在数据库中。接下来,使用该刷新令牌请求并验证JWT。从现在开始,每个请求都在头文件中包含此JWT。每当我的应用程序打开时,我也会请求新的JWT,即在我的Splash页面中。

现在,如果任何请求包含过期的JWT,只需返回一个常见的响应,例如"会话已过期" ,其中包含固定的状态代码。如果任何HTTP请求在其响应中具有此特定状态代码,则我请求使用刷新令牌进行另一个API调用以获取新的JWT以用于将来的请求。

由于我需要在每个HTTP响应中添加此检查(是否包含" Session Expired" ),我编写了一个通用函数并通过该方法传递HTTP响应,因此那,我不需要重写或复制粘贴它的每一点。

这需要非常少的代码和服务器和应用程序端的最小操作。我的系统的JWT到期时间为20分钟,到目前为止我还没有遇到任何问题。最糟糕的是,在单个请求中,用户收到令牌过期,获取令牌并回忆该功能。这导致已经在我的应用程序中连续超过20分钟的用户略微延迟操作。如果任何用户长时间在我的应用程序中,那么这是一个很好的问题,对吧? :)

目前尚不清楚用户是否必须每次登录您的应用或会话,以便登录用户可以直接进入该应用。如果会话处于保持状态,只需将refreshToken保存在应用程序本地(SharedPref)中,并在每次打开应用程序时使用它来获取JWT。如果任何用户滥用您的API(抓取或用于任何其他目的),只需将该特定刷新令牌移动到黑名单,以便该用户不会获得新的JWT。

如果有什么不清楚,请告诉我。感谢。