简体   繁体   中英

Implementation of Alamofire RequestInterceptor with refreshToken

I'm trying to handle 401 unauthorized request with Alamofire (5.6.1)

which Alamofire implementation should I use?

At first login post method I'm getting that kind of data:

 {
   "authToken": "auth12345",
   "refreshToken": "refresh6789"
 }

after that for each request to my API end point (ex. baseURL + " /user/api/user-address ")
I'm using that header with authToken

["Authorization": "Bearer \(authToken)", "Accept": "application/json"]

At the moment of expiration of authToken I starting to receive 401 code - which is unauthorized request.

To get new authToken I have to make request with refreshToken to specific endpoint which is:

baseURL + /auth/api/refresh-token

By reading alamofire doc I'm a bit confusing which implementation RequestInterceptor I have to go with:

RequestAdapter, RequestRetrier - says to implement:

1. func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void)

2. func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void)

but as I see example:

func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
    var urlRequest = urlRequest
    urlRequest.headers.add(.authorization(bearerToken: accessToken))

    completion(.success(urlRequest))
}

it's just modifies header ( headers.add ) with same expired accessToken and not gives you option

to make a call to specific endpoint with refreshToken

There also example of implementation class OAuthAuthenticator: Authenticator and

struct OAuthCredential: AuthenticationCredentia which is also not visible for me for providing

mechanism for dedicated endpoint to refresh authToken with refreshToken.

If you can check whether your token is expired ahead of time, you can implement the refresh in the adapt method:

func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  // Check token expiration.
  // If expired, call refresh, then call completion.
  // If not expired, adapt the request like normal and call completion.
}

If you can't do that, just implement the normal adapt you already have and implement the refresh in retry :

func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
  // If error is 401, refresh the tokens, then call the completion handler to trigger retry.
  // Retrying the request should then call adapt with the new token.
  // If the error isn't 401 and you don't want to retry, call completion(.doNotRetry).
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM