会话到期设计模式

mat*_*way 36 authentication ios

我经常不得不应对在iOS应用程序设计中过期的会话/访问令牌,并且从未真正找到我100%舒适的设计,所以我在这里问这里是否有人能想出更好的设计比我目前使用的.

问题

您有一个使用用户名和密码登录的应用程序.服务器返回一个访问令牌,该令牌应该用于将来对该用户进行身份验证的请求.在将来的某个时间点(未知时间),服务器将使该令牌到期,并且使用该令牌发送的任何请求都将返回身份验证失败.

由于会话过期而导致失败,应用程序应使用原始凭据重新登录并获取新的访问令牌.然后它可以重试原始请求.

因此,假设您有一个API来获取需要身份验证的新闻文章列表.流程可能如下:

  1. 用户登录和应用程序接收令牌.
  2. 视图控制器刷新新闻文章列表.
    1. API请求是使用附加的令牌进行的.
    2. API请求成功并使用新文章更新视图.
  3. 应用已关闭,一段时间过去了.
  4. 应用程序打开,此时视图控制器想要刷新新闻文章列表.
    1. API请求是使用附加的令牌进行的.
    2. API请求失败,因为令牌已过期.
    3. 视图控制器请求刷新令牌并耐心等待.
    4. 刷新令牌后,将重试API请求.

现在想象一下,这是从应用程序中的多个位置完成的.

我目前如何解决它

我通常做的是存储凭证NSUserDefaults(如果我不关心那些凭证的安全性 - 显然更好地使用密钥链)然后在全局管理器对象(单例)上有一个方法,当使用这些凭据刷新登录时我注意到会话已过期.当登录状态发生变化时,此全局管理器会触发通知,以便应用程序的其他部分可以知道何时由于会话过期而应该在失败后重试请求.

我觉得不对劲

好吧,我从来没有喜欢过经理对象的状态机处理.执行请求的每个位置都需要保存一些状态才能知道登录刷新正在进行,并在刷新登录后重试请求.还有一个问题,如果刷新因为密码错误而导致该怎么办(用户可能更改了它) - 你可能不想完全注销并破坏应用程序的所有用户状态,因为你可能只是能够像以前一样要求新密码并继续进行.但是全局管理器并没有真正与UI相关联,因此很难处理要求新登录的UI.

我想在答案中知道什么

我知道这个问题特别模糊和概念化(我仍然认为可以在StackOverflow上工作吗?)但我真的只想知道其他人如何解决这类问题.只是解释您如何处理会话过期,重试来自整个应用程序的失败请求,并在刷新不起作用时向用户询问新凭据.

我想整件事的关键是这个问题:

在何处放置由于会话到期而失败的请求的重试逻辑.我看到这些地方是可选的:

  1. 在视图控制器级别(即保持一个标志,表示我们需要在登录刷新完成后重试最后一个请求).
  2. 在API请求级别(即将API请求封装在知道在刷新登录后重试的对象中).
  3. 在全局登录管理器级别(即refreshLogin,一旦刷新登录,可能会在调用时执行一个块).

Sta*_*org 5

不要从死里复活这个问题,但既然没有得到回答,我会给出我的意见.

我为这种情况选择做的是将信用卡存储在钥匙串中(或者在任何地方,真的),然后我将HTTPClient子类化,以在每次调用之前检查是否刷新.通过这种方式,我可以识别需要刷新,执行它,并在一个步骤中重试所有调用,并且如果有必要可以在链中发送错误块以处理用户无法相应刷新的任何情况. .

这似乎与您(或可能是)试图完成的内容一致.不需要通知或任何爵士乐,您可以编写一次,并通过发送您的调用通过子类HTTPClient在整个应用程序中重复使用它.

编辑:请记住,你应该记得允许任何身份验证调用通过!


Mun*_*ndi 0

您在问题中提到了两件事,这似乎是回答该问题的关键:

A) 应用程序处于数据状态,如果用户未登录,数据可能会丢失。B
) 应用程序需要重新登录才能保存数据。

如果这些是限制,您应该相应地解决它们:

  1. 设计一个可以在本地保存更改的方案。跟踪与服务器的同步状态。
  2. 如果登录状态发生变化并且发生意外情况,请低调地提醒用户并给她修复问题的机会。