我需要解决的情况-想象一下同时发出2个请求(当访问令牌无效时)。两者都尝试刷新令牌,但是其中之一会使另一令牌失效。
有什么方法可以做吗:
还是您有其他解决方法的想法吗?
这是我的请求在每个视图控制器中的外观:
AF.request(encodedURLRequest, interceptor: AuthInterceptor()).validate().responseData { (response) in
...
}
这是我的AuthInterceptor:
final class AuthInterceptor: RequestInterceptor {
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
var adaptedUrlRequest = urlRequest
adaptedUrlRequest.setValue("Bearer \(UserDefaults.standard.getAccessToken())", forHTTPHeaderField: "Authorization")
completion(.success(adaptedUrlRequest))
}
func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
print("request \(request) failed")
if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 403 {
guard let url = URL(string: Endpoint.login.url) else { return }
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
urlRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let parameters: [String: String] = [
"refresh_token": UserDefaults.standard.getRefreshToken(),
"grant_type": "refresh_token"
]
guard let encodedURLRequest = try? URLEncodedFormParameterEncoder.default.encode(parameters,
into: urlRequest) else { return }
AF.request(encodedURLRequest).validate().responseData { (response) in
if let data = response.data {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
if let loginResponse = try? decoder.decode(LoginResponse.self, from: data) {
UserDefaults.standard.setAccessToken(value: loginResponse.accessToken)
UserDefaults.standard.setRefreshToken(value: loginResponse.refreshToken)
completion(.retryWithDelay(1))
}
}
}
}
}
}
答案 0 :(得分:0)
您可以使用Alamofire的RequestRetrier
协议(作为RequestInterceptor
协议的一部分)来执行此操作,而不必手动启动和停止请求。
本质上,您需要知道何时执行刷新,并存储由于令牌过期而失败的请求中的所有其他完成处理程序。您可以在AuthInterceptor
类中执行此操作。只要确保您的实现是线程安全的!