Omar El Halabi
Omar El Halabi

Reputation: 2128

How to add interceptor to all API requests except one or two?

I know it's possible to add an interceptor to all requests through an OkHttpClient, but I would like to know if it's possible to add headers to all requests in Okhttp except for one request or two using the OkHttpClient.

For example, in my API all requests require a bearer token (Authorization: Bearer token-here header) except for the oauth/token (to get a token) and api/users (to register a user) routes. Is it possible to add an interceptor for all requests except the excluded ones using the OkHttpClient in one step or should I add the headers individually for each request?

Upvotes: 12

Views: 5099

Answers (2)

Shahzain ali
Shahzain ali

Reputation: 1725

@Omar answer is Good :) but I found a more clean way to implement using custom annotation.

Add annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE

check if the annotation is true or false in an intercepter like this

val method = chain.request().tag(Invocation::class.java)!!.method()
    if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
       //when annotion is present
} else..

add an annotation in retrofit interface

@DECRYPTRESPONSE
@GET
Call<ItemsModel> getListing(@Url String url);

below is the complete code of my interceptor also don't forget to add intercepter in the Okhttpclient builder

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE

    class DecryptInterceptor : Interceptor {
    
        override fun intercept(chain: Interceptor.Chain): Response = chain
            .run {
                proceed(request())
            }
            .let { response ->
                return@let if (response.isSuccessful) {
    
                    val body = response.body!!
                    val contentType = body.contentType()
                    val charset = contentType?.charset() ?: Charset.defaultCharset()
                    val buffer = body.source().apply { request(Long.MAX_VALUE) }.buffer()
                    val bodyContent = buffer.clone().readString(charset)
    
                    val method = chain.request().tag(Invocation::class.java)!!.method()
    
                    if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
                        response.newBuilder()
                            .body(ResponseBody.create(contentType, bodyContent.let(::decryptBody)))
                            .build()
                    }
                    else{
                        response.newBuilder()
                            .body(ResponseBody.create(contentType, bodyContent))
                            .build()
                    }
    
                } else response
            }
    
        private fun decryptBody(content: String): String {
            
              return content //your decryption code
        }
    }

Upvotes: 5

Omar El Halabi
Omar El Halabi

Reputation: 2128

I found the answer!

Basically I needed an interceptor as usual and I needed to check the URL there to know whether I should add the authorization header or not.

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by Omar on 4/17/2017.
 */

public class NetInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (request.url().encodedPath().equalsIgnoreCase("/oauth/token")
                || (request.url().encodedPath().equalsIgnoreCase("/api/v1/users") && request.method().equalsIgnoreCase("post"))) {
            return  chain.proceed(request);
        }
        Request newRequest = request.newBuilder()
                .addHeader("Authorization", "Bearer token-here")
                .build();
        Response response = chain.proceed(newRequest);
        return response;
    }
}

Upvotes: 22

Related Questions