문제
- 보안상의 이유로 access 토큰 기간이 만료되면 api통신을 통해 다시 token을 받아야 하는데 어떻게 그걸 감지하고 api 통신을 요청할 수 있을까?
Interceptor

- 서버에 요청을 보내기 전에, 중간에 가로채서 어떤 작업을 한 뒤 다시 서버로 보내는 역할
- Alamofire를 사용하면 RequestInterceptor 프로토콜을 준수한 클래스의 인스턴스를 request에 실어서 보내면 동작
- adapt(): API 호출 전에 urlRequest에 관한 처리를 가로채서 적용하는 메서드
- retry(): API 호출 결과로 Error가 발생한 경우, 처리한 다음에 Error가 발생한 API를 다시 호출할것인지 적용하는 메서드
adapt()
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
guard let token = try? LoginManager.shared.tokenSubject.value() else{
completion(.success(urlRequest))
return
}
var urlRequest = urlRequest
urlRequest.setValue(token.authToken, forHTTPHeaderField: "X-AUTH-TOKEN")
completion(.success(urlRequest))
print(" adpat \(urlRequest)")
}
- api 호출 전 현재 토큰 값을 불러와 request에 header에 넣어준다.
retry()
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 {
completion(.doNotRetryWithError(error))
return
}
LoginAPI.autoLoginToken { response in
switch response.result {
case .success(var token):
token.existedMember = true
LoginManager.shared.tokenSubject.onNext(token)
KeychainManager.create(token: token)
print("토큰 갱신 성공")
completion(.retry)
case .failure(let error):
completion(.doNotRetryWithError(error))
}
}
}
- 401에러의 경우 토큰 기간이 만료된 것이므로 서버에 토큰 재발급 api 통신을 한다.