free geoip
41

Handle API 403/401 Unauthorized Error in Kotlin

Handling API 403 and 401 Unauthorized errors is essential when building secure Kotlin Android applications that rely on web services.…

Handling API 403 and 401 Unauthorized errors is essential when building secure Kotlin Android applications that rely on web services. These HTTP status codes indicate that the user is either unauthorized (401) or forbidden (403) to access a resource, usually due to invalid credentials or missing access tokens.

In Kotlin-based Android development using Retrofit, the best practice is to intercept these responses, notify the user, and redirect them to login or token refresh logic.

Here is a complete working example to handle 401/403 API errors using Retrofit and OkHttp interceptor in Kotlin.

Step 1: Add Retrofit & OkHttp dependencies (in build.gradle):

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"

Step 2: Create an AuthInterceptor.kt

class AuthInterceptor(private val tokenProvider: () -> String?) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val token = tokenProvider()
        val request = chain.request().newBuilder()
            .apply {
                if (!token.isNullOrEmpty()) {
                    header("Authorization", "Bearer $token")
                }
            }
            .build()

        val response = chain.proceed(request)

        if (response.code == 401 || response.code == 403) {
            // You can log out the user or refresh token here
            println("Unauthorized or Forbidden. Code: ${response.code}")
        }

        return response
    }
}

Step 3: Create Retrofit Instance (ApiClient.kt)

object ApiClient {

    private val retrofit: Retrofit

    init {
        val client = OkHttpClient.Builder()
            .addInterceptor(AuthInterceptor { getTokenFromPrefs() })
            .build()

        retrofit = Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    fun <T> create(service: Class<T>): T = retrofit.create(service)

    private fun getTokenFromPrefs(): String? {
        // Replace this with real SharedPreferences or DataStore logic
        return "your_token_here"
    }
}

Step 4: Define Your API Interface (ApiService.kt)

interface ApiService {
    @GET("user/profile")
    suspend fun getUserProfile(): Response<UserProfile>
}

Step 5: Use the API in Your ViewModel or Repository

val api = ApiClient.create(ApiService::class.java)

viewModelScope.launch {
    val response = api.getUserProfile()
    if (response.isSuccessful) {
        val user = response.body()
        // Handle success
    } else {
        // Handle other error codes
        Log.e("API_ERROR", "Error: ${response.code()}")
    }
}

This setup ensures you handle 401/403 errors in a centralized manner using interceptors. It also prepares your codebase for further enhancements like token refresh workflows or user logout.

For more best practices on secure API integration, check out Retrofit’s official documentation.

rysasahrial

Leave a Reply

Your email address will not be published. Required fields are marked *