会话过期的设计模式 [英] Session expire design pattern

查看:181
本文介绍了会话过期的设计模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常不得不应付会话/访问令牌在iOS应用设计到期,从来没有真的挺发现,我很舒服,100%设计,所以我问这个位置,看是否有人能够拿出一个更好的设计比我目前使用的。

问题

您有一个用户名和密码登录的应用程序。服务器返回一个应被用于将来的请求给该用户进行认证的接入令牌。在未来的(未知时间)的一些点的服务器将过期的令牌,并与该令牌发送的任何请求将返回一个身份验证失败。

失败后,由于会话过期,应用程序使用原始凭证应重新登陆并取回一个新的访问令牌。然后,它可以重试原来的请求。

示例

所以,想象一下你有一个API来获取需要身份验证的新闻文章的列表。流程可能是这样的:


  1. 在用户登录和应用获得令牌。

  2. 查看器刷新的新闻文章的列表。

    1. API请求附加记号的。

    2. API请求成功,视图与新文章更新。


  3. 应用被关闭,一些时间的流逝。

  4. 应用是在这一点上的看法控制器要刷新的新闻文章的列表中打开。

    1. API请求附加记号的。

    2. 因为令牌已过期API请求不成功。

    3. 查看控制器请求令牌的刷新和耐心等待。

    4. 当令牌已被刷新,API重试请求。


现在想象这是从多个位置的应用程序完成的。

我现在如何解决它

我最常做的是保存在 NSUserDefaults的的凭据(如果我不跟这些证书的安全性有关 - 显然不如使用钥匙串),然后有一个在全球管理对象(单身)方法使用这些的凭据刷新登录时,我注意到,本次会议已过期。这一全球经理触发关闭通知时登录状态的变化,使应用程序的其他部分可以知道他们什么时候应该重新尝试失败后的请求,由于会话过期。

我不觉得是对的

好吧,我只是从来没有喜欢管理器对象的状态机处理。执行一个请求每个地方需要保存一些状态,要知道,登录刷新是怎么回事,重试请求的登录已被刷新后。还有,如果刷新失败,因为密码现在是错误做什么的问题(用户改变了它也许) - 你可能不希望完全退出并销毁程序的所有用户状态,因为你可能只是能够索要新密码,并像以前一样继续。但全球经理并没有真正涉及到用户界面,所以很难把它处理要求新的登录的用户界面。

我想在回答知道什么

据我所知,这个问题显得尤为含糊不清和概念(我仍然认为这是确定要上StackOverflow的关系吗?),但我真的只是想知道其他人是如何解决这样的问题。你如何去了解来自全国各地的应用程序处理会话过期,重试失败的请求,并要求用户输入新的凭据清爽不工作只是一个解释。

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

如果把失败是由于到期会话请求的重试逻辑。我看到这些地方都是选项:


  1. 在视图控制器级别(即保持一个标志,说我们需要重试最后一次请求刷新登录已完成)。

  2. 在API请求级别(即封装在知道要重新尝试登录已被刷新之后的对象API请求)。

  3. 在全球的登录管理水平(即可能采取一次登录已被刷新,在执行时 refreshLogin 被称为块)。


解决方案

不要从死里复活了这个问题,但由于它没有得到回答,我给我的意见。

我选择了这个场景做的是vim的信任状存储在钥匙串(或其它地方,真的),然后我子类的了HTTPClient检查是否刷新或不是每一个呼叫。这样一来,我可以找出需要刷新,执行它,然后重试通话只需一个步骤,以及能够在必要时发送一个错误块了链来处理,用户无法进行相应更新的情况下,

这似乎是符合你是什么(或者可能是)试图完成。无需通知或任何爵士乐,你可以通过该子类了HTTPClient。

发送您的通话编写一次并重复使用在整个应用程序

编辑:!记住,你应该记住允许任何身份验证电话通

I have often had to cope with sessions / access tokens expiring in an iOS app design and have never really quite found a design that I am 100% comfortable with, so I am asking this here to see if anyone can come up with a better design than I currently use.

The problem

You have an app that logs in with a username and password. The server returns an access token that should be used for future requests to authenticate that user. At some point in the future (unknown time) the server will expire that token and any request sent with that token will return an authentication failure.

After failure due to the session expiring, the app should re-login using the original credentials and get back a fresh access token. It can then retry the original request.

Example

So imagine you have an API to get a list of news articles that requires authentication. The flow might go like this:

  1. User logs in and app receives token.
  2. View controller refreshes list of news articles.

    1. API request is made with token attached.
    2. API request successful and view is updated with new articles.

  3. App is closed and some time passes.
  4. App is opened at which point the view controller wants to refresh the list of news articles.

    1. API request is made with token attached.
    2. API request is unsuccessful because token has expired.
    3. View controller requests a refresh of the token and waits patiently.
    4. Once token has been refreshed, API request is retried.

Now imagine that this is done from more than one place in the app.

How I currently solve it

What I usually do is store the credentials in NSUserDefaults (if I am not concerned with security of those credentials - obviously better to be using the keychain) and then have a method on a global manager object (singleton) which refreshes the login using these credentials when I notice that the session has expired. This global manager fires off notifications when the login state changes so that other parts of the app can know when they should retry a request after failure due to the session expiring.

What I don't feel is right

Well, I just never have liked the state machine handling of the manager object. Every place that performs a request needs to save some state to know that a login refresh is going on and to retry the request after the login has been refreshed. There's also the problem of what to do if the refresh fails because the password is wrong now (the user changed it maybe) - you probably don't want to log out completely and destroy all user state of the app, because you might just be able to ask for the new password and carry on as before. But the global manager doesn't really relate to UI so it's hard to it to handle the UI of asking for the new login.

What I want to know in answers

I understand that this question is particularly vague and conceptual (I still think it's OK to be on StackOverflow though?) but I'd really just like to know how other people solve this kind of problem. Just an explanation of how you go about handling the session expiration, retrying the failed requests from all over the app and asking the user for new credentials if refreshing didn't work.

I guess the crux of the whole thing is this question:

Where to put the retry logic of requests that failed due to session expiring. I see these places are options:

  1. At the view controller level (i.e. keep a flag to say we need to retry the last request once login refresh has finished).
  2. At the API request level (i.e. encapsulate the API request in an object that knows to retry after the login has been refreshed).
  3. At the global login manager level (i.e. perhaps take a block in when refreshLogin is called that is executed once the login has been refreshed).

解决方案

Not to raise this question from the dead, but since it hasn't been answered I'll give my input.

What I chose to do for this scenario was to store the creds in the keychain (or wherever, really), and then I subclassed an HTTPClient to check whether to refresh or not before every call. This way, I can identify a refresh is needed, perform it, and retry the call all in one step as well as being able to send an error block up the chain if necessary to handle any cases in which the user could NOT be refreshed accordingly.

This seems to be in line with what you are (or probably were) trying to accomplish. No need for notifications or any of that jazz, and you can write it once and reuse it throughout the entire app by sending your calls through that subclassed HTTPClient.

EDIT: Bear in mind, you should remember to allow any authentication calls to pass!

这篇关于会话过期的设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆