Last active
July 16, 2020 06:16
-
-
Save Josscii/9ca97afe0e32987488023a721962dfbb to your computer and use it in GitHub Desktop.
如何用 alamofire 处理 JWT 过期?(不适用于不拿http状态码做错误码的方式
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://www.avanderlee.com/swift/authentication-alamofire-request-adapter/ | |
/// The storage containing your access token, preferable a Keychain wrapper. | |
protocol AccessTokenStorage: class { | |
typealias JWT = String | |
var accessToken: JWT { get set } | |
} | |
final class RequestInterceptor: Alamofire.RequestInterceptor { | |
private let storage: AccessTokenStorage | |
init(storage: AccessTokenStorage) { | |
self.storage = storage | |
} | |
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) { | |
guard urlRequest.url?.absoluteString.hasPrefix("https://api.authenticated.com") == true else { | |
/// If the request does not require authentication, we can directly return it as unmodified. | |
return completion(.success(urlRequest)) | |
} | |
var urlRequest = urlRequest | |
/// Set the Authorization header value using the access token. | |
urlRequest.setValue("Bearer " + storage.accessToken, forHTTPHeaderField: "Authorization") | |
completion(.success(urlRequest)) | |
} | |
func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) { | |
guard let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 else { | |
/// The request did not fail due to a 401 Unauthorized response. | |
/// Return the original error and don't retry the request. | |
return completion(.doNotRetryWithError(error)) | |
} | |
refreshToken { [weak self] result in | |
guard let self = self else { return } | |
switch result { | |
case .success(let token): | |
self.storage.accessToken = token | |
/// After updating the token we can safily retry the original request. | |
completion(.retry) | |
case .failure(let error): | |
completion(.doNotRetryWithError(error)) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment