使用 Swift p2/OAuth2 并行刷新 OAuth2 访问令牌请求

2024-05-05

我在用https://github.com/p2/OAuth2 https://github.com/p2/OAuth2用于通过 OAuth2 连接到我的应用程序的后端,效果非常好。

我遇到的问题是,当访问令牌过期并且同时发生多个请求时,其中一些请求会失败。

并行请求可以从应用程序的不同部分触发。例如,当应用程序启动时,当前位置将发送到服务器并下载事件列表。

确保第一个刷新令牌请求仍在运行时不会发出第二个刷新令牌请求的最佳方法是什么?


找到您的令牌生命周期并设置缓冲区,例如 1-2 分钟和 如果您的 token 需要刷新,请在 token 刷新时保存所有请求。之后执行所有保存的所有请求。您可以使用 DispatchQueue 和 DispatchWorkItem 来完成此操作。

下面的示例代码。

final class Network: NSObject {

    static let shared = Network()

    private enum Constants {
        static let tokenRefreshDiffrenceMinute = 1
        static let tokenExpireDateKey = "tokenExpireDate"
    }

    private(set) var tokenExpireDate: Date! {
        didSet {
            UserDefaults.standard.set(tokenExpireDate, forKey: Constants.tokenExpireDateKey)
        }
    }

    public override init() {
        super.init()

        if let date = UserDefaults.standard.object(forKey: Constants.tokenExpireDateKey) as? Date {
            tokenExpireDate = date
            print("Token found!")
        }
        else {
            print("Token not found!")
            isTokenRefreshing = true
            getToken {
                self.isTokenRefreshing = false
                self.executeAllSavedRequests()
            }
        }
    }


    private var isTokenRefreshing = false
    private var savedRequests: [DispatchWorkItem] = []

    func request(url: String, params: [String: Any], result: @escaping (String?, Error?) -> Void) {

        // isTokenRefreshing save all requests
        if isTokenRefreshing {

            saveRequest {
                self.request(url: url, params: params, result: result)
            }

            return
        }

        // if token expire
        if getMinutesFrom2Dates(Date(), tokenExpireDate) < Constants.tokenRefreshDiffrenceMinute {

            // open this flag for we need wait refresh token
            isTokenRefreshing = true

            // save current request too
            saveRequest {
                self.request(url: url, params: params, result: result)
            }


            // get token
            self.getToken { [unowned self] in
                self.isTokenRefreshing = false
                self.executeAllSavedRequests()
            }
        } else {
            //Alamofire.request ...

            DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
                DispatchQueue.main.async(execute: {
                    result(url, nil)
                })
            }
        }
    }

    private func saveRequest(_ block: @escaping () -> Void) {
        // Save request to DispatchWorkItem array
        savedRequests.append( DispatchWorkItem {
            block()
        })
    }

    private func executeAllSavedRequests() {
        savedRequests.forEach({ DispatchQueue.global().async(execute: $0) })
        savedRequests.removeAll()
    }

    private func getToken(completion: @escaping () -> Void) {
        print("Token needs a be refresh")
        // Goto server and update token
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) { [unowned self] in
            DispatchQueue.main.async(execute: { [unowned self] in
                self.tokenExpireDate = Date().addingTimeInterval(120)
                print("Token refreshed!")
                completion()
            })
        }
    }

    private func getMinutesFrom2Dates(_ date1: Date, _ date2: Date) -> Int {
        return Calendar.current.dateComponents([.minute], from: date1, to: date2).minute!
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Swift p2/OAuth2 并行刷新 OAuth2 访问令牌请求 的相关文章

  • ios7 navigationController PushViewController 动画错误

    看来我在 navigationController PushViewController 方法中发现了一个错误 为了重新创建它 我采用了示例主详细信息项目并对 didSelectRow method void tableView UITab
  • 使用 Azure AD 通过 OAuth2 对 Azure API 管理进行身份验证

    我正在尝试通过 AzureAD 使用 OAuth2 来保护 APIM API 方法是阅读以下文章 通过 Azure AD 使用 OAuth 2 0 授权来保护 Azure API 管理中的 Web API 后端 https learn mi
  • Swift:如何减少 didupdatelocations 调用

    我想出了一些代码来打印我所在位置的地址和邮政编码 这是在 didupdatelocation 函数中完成的 我遇到的唯一问题是 didupdatelocation 函数每秒都会更新该地址 因为这电池效率非常低 所以我一直在寻找使用间隔的方法
  • 为什么在授予用户权限时,UIUserNotificationType.None 在当前设置中返回 true?

    我正在编写一种方法来检查当前用户设置是否包含某些通知类型 当检查当前设置是否包含 UIUserNotificationsType None 时 无论授予权限还是拒绝权限 它都会返回 true 有谁知道这是为什么吗 func register
  • 在 IOS 上使用 AVComposition 混合两个音频文件

    我正在尝试混合两个音频文件 将一个音频文件放在另一个音频文件之上 不是缝合在一起 但我在 IOS 上学习 AVFoundation 时遇到了困难 我在这里遵循了这个答案 如何使用 AVMutableCompositionTrack 合并音频
  • Swift Codable 将空 json 解码为 nil 或空对象

    这是我的代码 class LoginUserResponse Codable var result String var data LoginUserResponseData var mess String public class Log
  • 用于字数计算的 Swift String 中的字数

    我想做一个程序来找出字符串中有多少个单词 用空格 逗号或其他字符分隔 然后把总数加起来 我正在制作一个平均计算器 所以我想要数据总数 然后将所有单词相加 update Xcode 10 2 x Swift 5 或更高版本 使用基础方法enu
  • 如何将字符串日期转换为 NSDate?

    我想转换字符串 2014 07 15 06 55 14 198000 00 00 to an NSDate在斯威夫特 尝试这个 let dateFormatter NSDateFormatter dateFormatter dateForm
  • 如何在 iOS 中更改部分透明图像的颜色?

    我有一个具有部分透明度的单色图像 我有正常版本和 2X 版本的图像 我希望能够用代码将图像着色为不同的颜色 下面的代码适用于普通图像 但 2X 最终会出现伪影 正常图像可能有类似的问题如果是这样 由于分辨率的原因我无法检测到它 UIImag
  • 所需框架与静态库

    构建现代框架 https developer apple com videos play wwdc2014 416 says 每个应用程序都有自己的自定义框架副本 https stackoverflow com a 15262463 242
  • 添加自定义过渡会导致 xib 加载错误的屏幕尺寸

    我正在尝试向具有 xib 的 UIViewController 添加自定义过渡 我尝试了几种方法 但它们都有相同的问题 视图显示的屏幕尺寸错误 我当前的示例基于以下教程 使用 Swift 在 iOS 中自定义 UIViewControlle
  • 如何在 Swift 中获取字典中最后输入的值?

    如何获取 Swift 字典中最后输入的值 例如 我如何从下面获取值 CCC var dictionary Dictionary
  • iOS 中的构建对象文件扩展名是什么?

    当我在项目中构建java对象类时 将创建带有 class扩展名的构建文件 并且人类不可读 快速构建文件怎么样 example car java gt build gt car class 构建后会是什么 car swift gt build
  • 如何恢复消耗品应用内购买?

    我正在开发一款 iOS 游戏 用户可以通过应用内消耗品购买一定数量的内部货币 比如 1000 金币 如果用户想将余额从一台设备转移到另一台设备 如何恢复消耗品购买 在苹果的文档中 它说我们必须使用我们自己的服务器 但是如何获取用户的Appl
  • 进入前台后刷新数据

    更改默认设置后 我想在AppDelegate中进入前台时刷新myViewController的数据 我所做的是 AppDelegate m void applicationDidFinishLaunching UIApplication a
  • 个人帐户开发者之间的 Apple 开发/分发证书

    我一直在到处寻找有关处理证书的正确答案 想象一下以下帐户 Joe拥有个人 Apple 帐户 但他根本不会编码 他只是发布了该应用程序并将其称为自己的 Bob还有一个个人 Apple 帐户 Bob 是一位编码专家 Joe 付费让他开发他的第一
  • 频繁绘制 CGPath 时的性能

    我正在开发一个将数据可视化为折线图的 iOS 应用程序 该图被绘制为CGPath在全屏自定义中UIView最多包含 320 个数据点 数据经常更新 图表需要相应地重新绘制 刷新率为 10 秒就很好了 到目前为止很容易 然而 我的方法似乎需要
  • 防止 AlertView 被解雇

    任何人都可以帮助我防止在其按钮单击事件上解雇警报视图吗 我有一个 textview 作为我的alertView 的子视图 如果 textview 值为 nil 我不想关闭它 因为这是一个非常老的问题 但我得到了一个解决方案 并且如果其他开发
  • RemoteIO 音频单元播放回调中的 AudioBufferList 内容

    我想 拦截 音频数据传送到 iOS 设备扬声器的过程 我相信这可以使用 RemoteIO 音频单元和回调来完成 在下面的playbackCallback中 ioData实际上包含任何音频数据吗 static OSStatus playbac
  • 为什么使用 iPhone 或 iOS 设备在“iframe”中查看“position:fixed”时不起作用?

    我研究过 stackoverflow 似乎position fixed在 iOS 移动设备的 iframe 中 https stackoverflow com questions 15874910 position fixed and if

随机推荐