iOS) RequestInterceptor이용하여 401 에러막기

CHAEYOUNG SONG·2022년 12월 1일
0

iOS

목록 보기
2/2
post-thumbnail

JWT토큰 만료시 401 에러 발생

iOS 앱 개발 도중 일어난 에러이다.

유저가 로그인시 자동로그인을 체크 했을때는 refreshToken을 이용하여 자동으로 로그인 될수 있도록 서버에서 로직을 만들어놨다.

유저가 일정시간동안 오래 앱을 실행하지 않았을 때는 토큰만료 에러인 401에러가 뜨면서 api가 실행되지 않는다.

뿐만아니라 여기서 재로그인을 위해 로그아웃을 실행하려해도 토큰자체가 만료가 났기 때문에 아예 로그인화면으로 돌아갈 수 조차 없다.

이를 해결하기 위해 RequestInterceptor를 이용하였다.

RequestInterceptor는 Alamofire에서 제공하는 프로토콜로 이 프로토콜에 포함된 retry함수를 사용한다면 401에러가 났을때 토큰을 재발급 받고 전에 호출됐던 api를 재호출 해준다.

Interceptor / JwtInterceptor 라는 클래스를 만들어 코드를 작성하였다.



import Alamofire

final class Interceptor: RequestInterceptor {

    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
        }
        if (UserDefaults.standard.string(forKey: "refreshToken") != nil){
            let authJwt = AuthJwtInput(refreshToken: UserDefaults.standard.string(forKey: "refreshToken"))
            AuthJwtDataManager().authJwtDataManager(authJwt)
            completion(.retry)
        }
    }
}

final class JwtInterceptor: RequestInterceptor {
    var window: UIWindow?
    var navigationController : UINavigationController?

    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
        }
        self.window = UIWindow(frame: UIScreen.main.bounds)
        navigationController = UINavigationController(rootViewController: LoginViewController())
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()
        completion(.retry)
    }
}

이렇게 구현한 메서드를 적용하기 위해서는 alamofire를 통해 요청할때 interceptor 파라미터를 통해 클래스를 전달해주어야 한다.




토큰재발급하는 api를 제외한 나머지 api에는 위쪽에 Interceptor라는 class를 적용하여 다시 토큰 재발급을 시도 할수 있도록 하였고, refreshToken마져 만료되어 토큰재발급 api에서도 401에러가 날때를 대비해 토큰 재발급api에는 아래쪽에 JwtInterceptor라는 class를 적용하여 다시 로그인 화면으로 돌아갈 수 있도록 하였다.

이것이 완벽한 해결책인지는 확신할 수 없지만 일단 문제가 되던 것들은 해결되었다.🥹

참조
https://bugle.tistory.com/53

0개의 댓글