Client OAuth pour Kotlin : intégration avec les fournisseurs via ktor-client et kotlinx-serialization

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Client OAuth pour Kotlin : intégration avec les fournisseurs via ktor-client et kotlinx-serialization

\n\n

OAuth 2.0 est un protocole d'autorisation standard qui permet aux applications d'obtenir un accès limité aux ressources d'un utilisateur sans transmettre ses identifiants. Dans l'écosystème Kotlin, grâce à la compatibilité JVM et à la multiplateforme, il est possible d'implémenter efficacement un client OAuth en utilisant des bibliothèques modernes. Dans cet article, nous allons créer un client OAuth en Kotlin avec ktor-client pour les requêtes HTTP et kotlinx-serialization pour le traitement JSON.

\n\n

Composants principaux du client OAuth

\n
    \n
  • Client HTTP — ktor-client pour envoyer des requêtes aux serveurs d'autorisation et de ressources.
  • \n
  • Sérialisation — kotlinx-serialization pour analyser les réponses en classes de données.
  • \n
  • Stockage des jetons — en mémoire ou persistant (SharedPreferences, fichiers).
  • \n
  • Gestionnaire d'états — traitement du code d'autorisation, du jeton d'actualisation, protection CSRF.
  • \n
\n\n

Ajout des dépendances

\n

Pour travailler avec OAuth en Kotlin, ajoutez les dépendances suivantes dans build.gradle.kts (ou build.gradle) :

\n
// build.gradle.kts\ndependencies {\n    implementation("io.ktor:ktor-client-core:2.3.12")\n    implementation("io.ktor:ktor-client-cio:2.3.12") // moteur\n    implementation("io.ktor:ktor-client-content-negotiation:2.3.12")\n    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.12")\n    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")\n    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")\n}
\n\n

Architecture de base du client OAuth

\n

Divisons la logique en trois couches :

\n
    \n
  • Modèles (DTO) — classes de données pour les requêtes/réponses.
  • \n
  • Service — classe gérant les flux d'autorisation.
  • \n
  • Client — wrapper autour de ktor-client avec des méthodes pour différents types de subventions.
  • \n
\n\n

Modèles de données

\n
import kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class TokenResponse(\n    @SerialName("access_token") val accessToken: String,\n    @SerialName("token_type") val tokenType: String = "Bearer",\n    @SerialName("expires_in") val expiresIn: Long? = null,\n    @SerialName("refresh_token") val refreshToken: String? = null,\n    @SerialName("scope") val scope: String? = null,\n    @SerialName("id_token") val idToken: String? = null // pour OpenID Connect\n)\n\n@Serializable\ndata class OAuthError(\n    val error: String,\n    @SerialName("error_description") val errorDescription: String? = null\n)
\n\n

Client OAuth2

\n
import io.ktor.client.*\nimport io.ktor.client.call.*\nimport io.ktor.client.plugins.contentnegotiation.*\nimport io.ktor.client.request.*\nimport io.ktor.client.statement.*\nimport io.ktor.http.*\nimport io.ktor.serialization.kotlinx.json.*\nimport kotlinx.serialization.json.Json\n\nclass OAuth2Client(\n    private val clientId: String,\n    private val clientSecret: String,\n    private val redirectUri: String,\n    private val tokenEndpoint: String,\n    private val authEndpoint: String\n) {\n    private val httpClient = HttpClient(CIO) {\n        install(ContentNegotiation) {\n            json(Json {\n                ignoreUnknownKeys = true\n                isLenient = true\n            })\n        }\n    }\n\n    // Génération de l'URL pour la redirection vers la page d'autorisation\n    fun getAuthorizationUrl(state: String, scope: String = "openid profile email"): String {\n        return "$authEndpoint?response_type=code" +\n                "&client_id=$clientId" +\n                "&redirect_uri=${java.net.URLEncoder.encode(redirectUri, "UTF-8")}" +\n                "&scope=${java.net.URLEncoder.encode(scope, "UTF-8")}                    

Recommendations