I'm trying to build network layer using Apollo, and got one problem. I'm using tutorial from Apollo docs to refresh tokens. And they said that I should provide interceptor to handle token expired date. I did it. But I should create network request to refresh token, and this request catch by interceptor too. How I can resolve it?
class NetworkInterceptorProvider: DefaultInterceptorProvider {
override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
var interceptors = super.interceptors(for: operation)
interceptors.insert(UserManagementInterceptor(), at: 0)
return interceptors
}
My UserManagementInterceptor:
func interceptAsync<Operation: GraphQLOperation>(
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void
) {
guard let token = AuthenticationService.shared.getAccessToken() else {
chain.handleErrorAsync(
UserError.noUserLoggedIn,
request: request,
response: response,
completion: completion
)
AuthenticationService.shared.status = .unauthenticated
print("No access token")
return
}
if AuthenticationService.shared.checkTokenExpired() {
print("Token expired")
guard let refreshToken = AuthenticationService.shared.getRefreshToken() else {
AuthenticationService.shared.status = .unauthenticated
print("No refresh token")
return
}
NetworkManager.shared.apollo.perform(mutation: Network.RefreshTokenMutation(token: refreshToken)) { [weak self] tokenRenewResult in
guard let self else { return }
switch tokenRenewResult {
case .failure:
AuthenticationService.shared.status = .unauthenticated
print("Filed request")
break
case let .success(token):
As result I've got recursion with "Token expired", because my network request RefreshTokenMutation passed through this interceptor too... How I can create exception for token refresh network method?
This is my solution:
class NetworkInterceptorProvider: DefaultInterceptorProvider {
override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
var interceptors = super.interceptors(for: operation)
if checkIsAuthorizationRequired(for: operation) {} else {
interceptors.insert(UserManagementInterceptor(), at: 0)
}
return interceptors
}
func checkIsAuthorizationRequired<Operation: GraphQLOperation>(for _: Operation) -> Bool {
let authLoginOperation = Operation.operationName == "AuthLoginMutation"
let refreshTokenOperation = Operation.operationName == "RefreshToken"
let signUp = Operation.operationName == "AuthSignUp"
if authLoginOperation || refreshTokenOperation || signUp {
return true
} else {
return false
}
}
}