Android Networking: Beyond the Basics

Sep 8 2022 · Kotlin 1.7.10, Android 12, Android Studio Chipmunk

Part 1: Implement Advanced Retrofit

05. Intercept Authentication

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 04. Challenge: Error Handling Next episode: 06. Challenge: Authentication & REST Methods

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 05. Intercept Authentication

Most server APIs require you to send an authorization token, whenever you’re trying to access an endpoint that requires a user id or email. This is why you’ve sent the user token as a header parameter in many requests. But it would be a cool thing if you could automatically send the token, once you’re logged in, right? Well, you can, using interceptors!

You can add another interceptor to Retrofit’s HTTP client, to intercept requests, and attach appropriate headers when the token is available. Then each request will be “authorized” by default, and you won’t have to manually think about the token. Let’s see how to do this!

Demo

Open the RetrofitBuilders.kt file, and start by adding this constant, to represent the authorization header:

private const val HEADER_AUTHORIZATION = "Authorization"

Then add another interceptor to Retrofit, with the following code:

.addInterceptor(buildAuthorizationInterceptor())

buildAuthorizationInterceptor() doesn’t exist yet, so let’s create it:

fun buildAuthorizationInterceptor() = object : Interceptor {
  override fun intercept(chain: Interceptor.Chain): Response {
    val originalRequest = chain.request()

    if (App.getToken().isBlank()) return chain.proceed(originalRequest)

    val new = originalRequest.newBuilder()
        .addHeader(HEADER_AUTHORIZATION, App.getToken())
        .build()

    return chain.proceed(new)
  }
}

This might seem complex, but it’s pretty simple. You create an interceptor, which receives an interceptor chain. The chain represents all the layers through which the API call goes, before returning a response.

Then you get the original request and check if there is a token saved in the app. If there isn’t, you simply proceed with the original request.

If there is a token, however, you create a new request, from the original one, which is slightly different because you add a header in the runtime. Then you proceed with the new request, instead of the original one. This will be done for every single request, so once you log in, you’ll be authorized for all the proceeding requests! :]

Now move to the RemoteApiService.kt, to remove the unnecessary header from the api calls. You can use the Refactor -> Change Signature option, and remove the parameter. This will also remove the arguments you send when invoking the function, so you don’t have to do a lot of work manually!

@GET("/api/note")
fun getNotes(): Call<GetTasksResponse>

@GET("/api/user/profile")
fun getMyProfile(): Call<UserProfileResponse>

@POST("/api/note/complete")
fun completeTask(@Query("id") noteId: String): Call<CompleteNoteResponse>

@POST("/api/note")
fun addTask(@Body request: AddTaskRequest): Call<Task>

That should be it! :] Run the project, and the auth header should be added to every request once you’re logged in!

You no longer have to do it yourself! :]