I implemented the new AuthenticationInterceptor into my app, here is my actual code:
import Alamofire
import SwiftyJSON
struct OAuthCredential: AuthenticationCredential {
let accessToken: String
let refreshToken: String
let expiration: Date
// Require refresh if within 5 minutes of expiration
var requiresRefresh: Bool { Date(timeIntervalSinceNow: 60 * 15) > expiration }
}
class OAuthAuthenticator: Authenticator {
func apply(_ credential: OAuthCredential, to urlRequest: inout URLRequest) {
urlRequest.headers.add(.authorization(bearerToken: credential.accessToken))
}
func refresh(_ credential: OAuthCredential, for session: Session, completion: @escaping (Result<OAuthCredential, Error>) -> Void) {
NetworkManager.shared.oauth.doRefreshToken { (jsonDict, error) in
if let jsonDict = jsonDict {
let json = JSON(jsonDict)
let accessToken = json["access_token"].stringValue
let refreshToken = json["refresh_token"].stringValue
let expiration = json["expires_in"].doubleValue
let newCredential = OAuthCredential(accessToken: accessToken, refreshToken: refreshToken, expiration: Date(timeIntervalSinceNow: expiration))
completion(.success(newCredential))
}
}
}
func didRequest(_ urlRequest: URLRequest, with response: HTTPURLResponse, failDueToAuthenticationError error: Error) -> Bool {
return response.statusCode == 401
}
func isRequest(_ urlRequest: URLRequest, authenticatedWith credential: OAuthCredential) -> Bool {
let bearerToken = HTTPHeader.authorization(bearerToken: credential.accessToken).value
return urlRequest.headers["Authorization"] == bearerToken
}
}
The problem here is when for example I enter a screen where there're 3 API calls, refresh delegate is called also 3 times and refresh the token 3 times also.
What I want to achieve is to call "doRefreshToken" once and recall all APIs with the new token.
Thanks in advance.