사용자가 다시 로그인을 진행하도록 유도하고 새로운 토큰을 발급한다.
// MARK: - 401 validate
extension Observable where Element == (HTTPURLResponse, Data) {
fileprivate func validateAuthorized() -> Observable<(HTTPURLResponse, Data)> {
return map { response, data -> (HTTPURLResponse, Data) in
switch response.statusCode {
case 401:
DispatchQueue.main.async {
let appdelegate = UIApplication.shared.delegate as! AppDelegate
let storyboard = UIStoryboard(name: "Auth", bundle: nil)
let loginVC = storyboard.instantiateViewController(withIdentifier: "AuthNavi")
appdelegate.window?.rootViewController?.present(loginVC, animated: true, completion: nil)
print("--->[validateAuthorized]: statusCode: 401, Unauthorized")
}
return (response, data)
default:
return (response, data)
}
}
}
}
refresh Token으로 교체하기
- access token의 유효기간이 만료되어 갈 때 서버에서는 새로운 토큰을 미리 생성한다.
- 서버는 refresh Token을 response로 내려준다.
- request 할 때마다 validate를 이용해 response로 내려온 토큰과 기존의 토큰을 비교한다.
- response로 내려온 토큰과 기존 토큰이 다르면 토큰을 교체한다. (기존 토큰과 다른 토큰은 refresh Token으로 간주)
// MARK: - refresh token
extension Observable where Element == (HTTPURLResponse, Data) {
fileprivate func validateRefreshToken() -> Observable<(HTTPURLResponse, Data)> {
return map { (response, data) -> (HTTPURLResponse, Data) in
switch response.statusCode {
case 200..<300:
if let oldToken = AccountService.getToken(),
let newToken = response.headers[HEADER_TOKEN],
oldToken != newToken {
/// Interceptor 토큰 교체
AccountService.interceptor = Interceptor(token: newToken)
/// 저장된 토큰 교체
AccountService.saveToken(newToken)
print("--->[validateRefreshToken] 토큰이 교체되었습니다.")
}
return (response, data)
default:
return (response, data)
}
}
}
}
cf.
http://www.ccheptea.com/2019-03-25-handling-rest-errors-with-rxswift/