Ситуацию, которую мне нужно исправить - представьте, что 2 запроса выполняются одновременно (когда токен доступа недействителен). Оба пытаются обновить токен, но один из них лишает законной силы токен для другого.
Есть ли способ как:
- разрешить только 1 обновлять токен
- остановить все остальные запросы
- перезапустить все остановленные запросы (при обновлении токена)
Или у вас есть идеи, как решить эту проблему другим способом?
Этотак выглядит мой запрос в каждом контроллере представления:
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))
}
}
}
}
}
}