Alamofire refreshToken with Retrier:如何获取 refreshToken 请求的状态并重新路由到 LoginView

Posted

技术标签:

【中文标题】Alamofire refreshToken with Retrier:如何获取 refreshToken 请求的状态并重新路由到 LoginView【英文标题】:Alamofire refreshToken with Retrier: how to get status of refreshToken request and reroute to LoginView 【发布时间】:2018-10-19 08:17:39 【问题描述】:

我根据Alamofire guide自定义refreshTokens函数。

当 refreshTokens 失败并从 API 服务器获得 401 状态时,我想重新路由到登录视图(对于其他错误状态,如 400 或 500,只需在视图中显示错误消息)。 目前我使用 UserDefaults 来通知视图的 401 状态(调用 Alamofire 请求)。

我想知道是否有更好的方法来通知视图的“刷新令牌状态”(或与视图和 oauth2handler 共享状态变量的方法)。

谢谢!

OAuth2Handler

    manager.request(urlString, method: .post, parameters: parameters, encoding: URLEncoding.default)
        .responseJSON  [weak self] response in
            guard let strongSelf = self else  return 

            if
                let json = response.result.value as? [String: Any],
                let accessToken = json["access_token"] as? String
            
                completion(true, accessToken)
             else 
                if let status = response.response?.statusCode, status == 401 
                    UserDefaults.standard.set(true, forKey: "login_required")

                
                completion(false, nil)
            

            strongSelf.isRefreshing = false
    

点击某个按钮时的 ViewController 动作

_ = client.request(API.addLike(json: comment))
    .subscribe(
        onSuccess:  (response) in
            // successful!
        ,
        onError:  (err) in
            let loginRequired = UserDefaults.standard.bool(forKey: "login_required")
            if loginRequired == true 
                print("refresh token is wrong or expired. login required")
                // transition to LoginView
             else 
                print("request is invalid or server is down.")
            
        
    )

【问题讨论】:

【参考方案1】:

我最近为我的一个应用处理了同样的情况。我创建了一个OAuthManager 类,它继承自RequestAdapterRequestRetrier

func adapt(_ urlRequest: URLRequest) throws -> URLRequest 中,我使用Authorization 令牌调整我的请求。

func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) 中,我正在检查请求的结果,然后再发送到 Alamofire 的完成处理程序。

在我的情况下,我可能会收到 401 错误代码,因为访问令牌已过期,或者仅仅是因为用户无权执行此操作。因此,我正在检查我的 REST API 发送的服务器消息,以确保访问令牌已过期并请求新的。

如果刷新令牌 API 返回错误,我会直接从 should 函数显示 LoginViewController,方法是:

let rootViewController = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "WELCOME_NAVIGATION")
UIApplication.shared.keyWindow?.rootViewController = rootViewController

我可以这样做,因为我的登录方法可从UIViewController 获得。如果你想使用UIView,你可以添加一个子视图到UIApplication.shared.keyWindow?.rootViewController.view

如果你想显示通知或类似的东西,也许使用NotificationCenter 来触发你的UIView 中的一些代码会更好。

问候,

IMACODE

【讨论】:

以上是关于Alamofire refreshToken with Retrier:如何获取 refreshToken 请求的状态并重新路由到 LoginView的主要内容,如果未能解决你的问题,请参考以下文章

refreshToken 端点实现在哪里?

Firebase:我啥时候应该使用 refreshToken?

Firebase 使用 idToken 或 refreshToken 登录

Cookie、Session、Token、RefreshToken

每个 refreshToken 的 OAuth2 访问令牌限制

Google+ 身份验证:refreshToken() 返回 invalid_grant 错误