Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 636
Omar El Halabi Avatar asked Apr 17 '17 10:04

Omar El Halabi


People also ask

How do I intercept API request?

To intercept HTTP requests, use the webRequest API. This API enables you to add listeners for various stages of making an HTTP request. In the listeners, you can: Get access to request headers and bodies and response headers.

How do you intercept HTTP request in Javascript?

js file (the actual service-worker code): To intercept requests, you attach a fetch event listener to the service worker that calls the respondWith() method and does something with the . request member from the event object: self. addEventListener('fetch', function(event) { event.

What is an API interceptor?

Interceptor is an API gateway server built for accepting API requests from the client applications and routing them to the appropriate backend services. May it be a single service or multiple services to be called in a single API call, interceptor provides you with the necessary tools to control your API request flow.

Does fetch have interceptors?

The Fetch API doesn't support interceptors natively. However, there are other libraries for making HTTP calls that support interceptors.


2 Answers

@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
        }
    }
like image 59
Shahzain ali Avatar answered Oct 19 '22 23:10

Shahzain ali


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;
    }
}
like image 22
Omar El Halabi Avatar answered Oct 19 '22 22:10

Omar El Halabi