适用于 Kotlin 的 OAuth 客户端:通过 ktor-client 和 kotlinx-serialization 与提供商集成

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

适用于 Kotlin 的 OAuth 客户端:通过 ktor-client 和 kotlinx-serialization 与提供商集成



OAuth 2.0 是一种标准的授权协议,允许应用程序在不传递用户凭据的情况下,获取对用户资源的有限访问权限。在 Kotlin 生态系统中,得益于与 JVM 的兼容性和多平台特性,可以使用现代库高效地实现 OAuth 客户端。在本文中,我们将探讨如何使用 ktor-client 进行 HTTP 请求,以及使用 kotlinx-serialization 处理 JSON,在 Kotlin 中创建 OAuth 客户端。



OAuth 客户端的主要组件

  • HTTP 客户端 — ktor-client,用于向授权服务器和资源服务器发送请求。
  • 序列化 — kotlinx-serialization,用于将响应解析为 data 类。
  • 令牌存储 — 内存存储或持久化存储(SharedPreferences、文件)。
  • 状态管理器 — 处理授权码、刷新令牌、CSRF 保护。


添加依赖项

要在 Kotlin 中使用 OAuth,请在 build.gradle.kts(或 build.gradle)中添加以下依赖项:

// build.gradle.ktsdependencies {    implementation("io.ktor:ktor-client-core:2.3.12")    implementation("io.ktor:ktor-client-cio:2.3.12") // 引擎    implementation("io.ktor:ktor-client-content-negotiation:2.3.12")    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.12")    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")}


OAuth 客户端的基本架构

我们将逻辑分为三层:

  • 模型(DTO) — 用于请求/响应的 data 类。
  • 服务 — 管理授权流程的类。
  • 客户端 — 对 ktor-client 的封装,提供不同授权类型的方法。


数据模型

import kotlinx.serialization.SerialNameimport kotlinx.serialization.Serializable

@Serializabledata class TokenResponse( @SerialName("access_token") val accessToken: String, @SerialName("token_type") val tokenType: String = "Bearer", @SerialName("expires_in") val expiresIn: Long? = null, @SerialName("refresh_token") val refreshToken: String? = null, @SerialName("scope") val scope: String? = null, @SerialName("id_token") val idToken: String? = null // 用于 OpenID Connect)

@Serializabledata class OAuthError( val error: String, @SerialName("error_description") val errorDescription: String? = null)


OAuth2 客户端

import io.ktor.client.*import io.ktor.client.call.*import io.ktor.client.plugins.contentnegotiation.*import io.ktor.client.request.*import io.ktor.client.statement.*import io.ktor.http.*import io.ktor.serialization.kotlinx.json.*import kotlinx.serialization.json.Json

class OAuth2Client( private val clientId: String, private val clientSecret: String, private val redirectUri: String, private val tokenEndpoint: String, private val authEndpoint: String) { private val httpClient = HttpClient(CIO) { install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true isLenient = true }) } }

// 生成重定向到授权页面的 URL fun getAuthorizationUrl(state: String, scope: String = "openid profile email"): String { return "$authEndpoint?response_type=code" + "&client_id=$clientId" + "&redirect_uri=${java.net.URLEncoder.encode(redirectUri, "UTF-8")}" + "&scope=${java.net.URLEncoder.encode(scope, "UTF-8")}

推荐