zar*_*nis 5 oauth ios nsurlsession swift
在发布问题之前,我进行了很多搜索,但是很遗憾,我无法找到问题的解决方案。
我开发了一个应用程序,该应用程序连接到需要使用access token和进行身份验证的服务器refresh token。
的access token有效期为1 hour,可以多次使用。
的refresh token有效期1 month和access token到期时使用。The refresh令牌只能使用一次。
当refresh token使用时,我得到一个新的refresh token,以及除access token。
这是我的问题:
我写了一个APIClient class,处理我的应用程序需要的所有请求。这class很有效,除非access token过期。当access token到期时,将在此时间运行将失败,所有的请求401 code(授权)。
我想要的是找到一个解决方案,该解决方案将刷新access token使用refresh token,然后重试所有失败的状态为status的请求code 401。请记住,刷新令牌的函数只能调用一次,因为refresh令牌仅对一种用途有效。
我想做的是找到一种写我的方法,APIClient class以便它支持令牌的刷新并重试所有失败的请求。如果您告诉我如何实现这一目标,我将不胜感激。
看一下下面的getRequest和sendRefreshRequest源代码。
func getRequestWith(requestType: FSRequestType, usingToken: Bool, parameters: RequestParameters?, completionClosure: @escaping (NetworkResult) -> Void) {
let sessioConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessioConfig, delegate: nil, delegateQueue: nil)
guard var URL = APIClient.baseURL?.appendingPathComponent(requestType.rawValue) else { return }
if let parameters = parameters {
URL = URL.appendingQueryParameters(parameters)
}
var request = URLRequest(url: URL)
request.httpMethod = "GET"
if usingToken {
let tokenString = "Bearer " + TokenManager.sharedManager.accessToken()!
request.addValue(tokenString, forHTTPHeaderField: "Authorization")
}
let task = session.dataTask(with: request) { (data, response, error) in
guard error == nil else { return completionClosure(.Error(error!.localizedDescription))}
guard let data = data else { return completionClosure(.Error("Could not load data")) }
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 401 {
//Handle refresh token
} else if statusCode == 200 {
let json = JSON(data: data)
let responseJSON = json["response"]
completionClosure(.Success(responseJSON))
} else {
completionClosure(.Error("Returned status code \(statusCode) from Get request with URL: \(request.url!)"))
}
}
task.resume()
}
func sendRefreshRequest() {
let session = URLSession(configuration: .default)
guard var URL = APIClient.baseURL?.appendingPathComponent(FSRequestType.RefreshToken.rawValue) else {return}
let URLParams = [
"refresh_token" : TokenManager.sharedManager.refreshToken()!
]
URL = URL.appendingQueryParameters(URLParams)
var request = URLRequest(url: URL)
request.httpMethod = "GET"
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200 {
let json = JSON(data: data!)
if TokenManager.sharedManager.saveTokenWith(json) {
print("RefreshedToken")
} else {
print("Failed saving new token.")
SessionManager.sharedManager.deauthorize()
}
} else if statusCode == 400 {
print("The refresh token is invalid")
SessionManager.sharedManager.deauthorize()
}
})
task.resume()
}
Run Code Online (Sandbox Code Playgroud)
谢谢
小智 1
我不使用 Swift 编写代码,因此无法为您提供代码,但我认为最简单的方法是:
1:定义你的completionBlock内心APIClient
APIClient2:在你的if (statusCode == 401)处理程序中处理内部的所有调用,
3:刷新完token后,可以检查是否成功completionBlock != nil,再次请求数据,成功则返回回调。
当您在 中执行所有刷新方法时APIClient,直到完成刷新并再次重试请求之前,您不会返回completionBlock。
调用的其他类APIClient将等待返回completionBlock,并且您可以传递completionBlock,直到获得正确的令牌并进行重试调用。
检查这些线程中有关如何定义 Swift 完成块的代码,您就会明白了。
| 归档时间: |
|
| 查看次数: |
1048 次 |
| 最近记录: |