首页 > 解决方案 > 如何维护用户登录会话?

问题描述

我正在尝试在我的 Android 应用程序中维护用户登录会话(1 小时)。当用户登录时,我从服务器接收登录时间(StartTime)和会话结束时间(Timemout)。

我正在使用 System api (System.currentTimeMillis()) 将收到的登录时间 + 会话结束时间与我当前的设备时间进行比较。

我的问题是用户可以通过更改位置或更改设备中的时钟时间来操作此 System.currentTimeMillis() 并且可以进行无限登录会话。

我还尝试使用依赖于启动时间的 SystemClock.elapsedRealtime()。用户可以通过重新启动设备来重置或操纵时间。

无论如何要保持1小时的登录会话?

从服务器接收的 StartTime 和 Timeout 时间。

((startTime + timeout) > (System.currentTimeMillis()/1000))

或者

((startTime + timeout) > (SystemClock.elapsedRealtime()/1000))

标签: javaandroidsessionsystemtime

解决方案


此处的目标是确保您的会话不超过一定的时间长度,无论您的设备本地时间有任何日期/时间更改。这里的一个常数是您的服务器的时间,所以让我们利用它。

  1. 在应用程序启动时,让您的应用程序查询服务器以查看它是否具有活动会话。如果没有,请向用户显示登录屏幕。
  2. 如果存在活动会话,则服务器应返回该会话的剩余持续时间。这意味着您的服务器将跟踪登录的设备以及登录时间。这样,当一个身份验证请求进来时,它会检查它的列表是否在最后一小时内成功登录,并返回当前时间和上次登录时间之间的差异。如果在最后一小时内没有成功登录,则请求失败
  3. 应用端,当认证请求成功时,我们会启动一个计时器来计算从服务器返回的时间长度。您可以自己实现,也可以只使用 ScheduledThreadPoolExecutor。无论如何,您的计时器不能在其实现中使用 System.currentTimeMillis() ,否则它将受到本地时间更改的影响。有关更多信息,请参阅答案。
  4. 当计时器结束时,您可以锁定用户并强制他们再次登录,或者只是让他们一直待着直到应用程序关闭。这取决于您和您在用户体验和安全方面的优先事项。

简而言之,应用程序始终处于两种状态之一。它要么未经身份验证并等待用户登录,要么已通过身份验证并在计时器上再次锁定用户。这样,您不必经常 ping 您的服务器来检查会话状态

正如前面的链接中提到的,System.nanoTime() 是一个很好的工具,可以在不受本地时间变化影响的计时器中使用。java 文档中的更多详细信息


推荐阅读