0Pricing
Kotlin Academy · 课时

身份验证插件:JWT 与会话

使用 JWT 持有者令牌和基于会话的身份验证保护 Ktor 路由。

身份验证插件:JWT 与会话 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

Ktor 身份验证概述

Ktor 的 Authentication 插件为保护路由提供了统一的 API。您可以配置一个或多个提供程序(JWT、Session、Basic、OAuth 等),然后将路由包裹在 authenticate("providerName") { } 块中。

添加身份验证依赖项

将身份验证库和 JWT 库添加到您的构建配置中:

dependencies {
    implementation("io.ktor:ktor-server-auth:2.3.12")
    implementation("io.ktor:ktor-server-auth-jwt:2.3.12")
    implementation("io.ktor:ktor-server-sessions:2.3.12")
}

配置 JWT 身份验证

安装 Authentication 插件并配置 JWT 提供程序。verifier 用于验证令牌签名,validate 用于从有效载荷中提取主体:

install(Authentication) {
    jwt("auth-jwt") {
        realm = "ktor app"
        verifier(
            JWT.require(Algorithm.HMAC256(secret))
                .withAudience(audience)
                .withIssuer(issuer)
                .build()
        )
        validate { credential ->
            if (credential.payload.getClaim("username").asString() != null)
                JWTPrincipal(credential.payload)
            else null
        }
    }
}

使用 JWT 保护路由

将任意路由组包裹在 authenticate("auth-jwt") { } 中。未经身份验证的请求会自动收到 401 响应:

routing {
    authenticate("auth-jwt") {
        get("/protected") {
            val principal = call.principal<JWTPrincipal>()!!
            val username = principal.payload.getClaim("username").asString()
            call.respondText("Hello, $username")
        }
    }
}

签发 JWT 令牌

在登录端点中使用 java-jwt 库生成并签署 JWT:

post("/login") {
    val user = call.receive<LoginRequest>()
    // validate credentials ...
    val token = JWT.create()
        .withAudience(audience)
        .withIssuer(issuer)
        .withClaim("username", user.username)
        .withExpiresAt(Date(System.currentTimeMillis() + 3_600_000))
        .sign(Algorithm.HMAC256(secret))
    call.respond(mapOf("token" to token))
}

会话身份验证

会话在服务器端存储用户状态(或者以已签名 Cookie 的形式存储在客户端)。请安装 Sessions 插件,并定义会话数据类:

data class UserSession(val userId: Long, val username: String)

install(Sessions) {
    cookie<UserSession>("user_session") {
        cookie.path = "/"
        cookie.httpOnly = true
    }
}

配置会话身份验证提供程序

创建一个会话身份验证提供程序,用于读取会话并返回主体:

install(Authentication) {
    session<UserSession>("auth-session") {
        validate { session -> session }
        challenge { call.respond(HttpStatusCode.Unauthorized) }
    }
}

设置和清除会话

登录后使用 call.sessions.set() 设置会话,退出登录时使用 call.sessions.clear() 清除会话:

post("/login") {
    val creds = call.receive<LoginRequest>()
    // validate ...
    call.sessions.set(UserSession(userId = 1L, username = creds.username))
    call.respond(HttpStatusCode.OK)
}

post("/logout") {
    call.sessions.clear<UserSession>()
    call.respond(HttpStatusCode.OK)
}

JWT 与会话:分别适用于何时

JWT:无状态,适合由移动客户端或 SPA 使用的 API。令牌包含所有声明,服务器无需会话存储。会话:有状态,适合服务端渲染的 Web 应用。Cookie 中存储会话 ID,服务器保存会话数据(内存、Redis 或数据库)。

组合多个身份验证提供程序

您可以定义多个提供程序,并使用 authenticate("jwt", "session") { } 要求其中任意一个提供程序通过验证。Ktor 会按顺序尝试每个提供程序,只要有一个验证成功,就会接受该请求。

自定义质询响应

每个提供程序都有一个 challenge 块,用于定义身份验证失败时的处理方式。您可以返回包含 JSON 错误正文的 401 响应,而不是默认的 WWW-Authenticate 标头:

jwt("auth-jwt") {
    // ...
    challenge { _, _ ->
        call.respond(HttpStatusCode.Unauthorized, mapOf("error" to "Token expired or invalid"))
    }
}

快速检查

Ktor JWT 提供程序中的 validate 块有什么作用?

回顾:身份验证插件——JWT 与会话

要点:

  • 安装 Authentication,并配置提供程序(jwt、session、basic、oauth)
  • 使用 authenticate("providerName") { } 保护路由
  • JWT:无状态令牌;在登录时签名,使用验证器验证,并在 validate 中读取声明
  • 会话:有状态;登录时使用 call.sessions.set(),退出登录时使用 clear()
  • 使用 challenge 自定义 401 响应的格式

常见问题解答

「身份验证插件:JWT 与会话」课时是免费的吗?

是的 — 「身份验证插件:JWT 与会话」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「身份验证插件:JWT 与会话」这节课中我会学到什么?

使用 JWT 持有者令牌和基于会话的身份验证保护 Ktor 路由。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「身份验证插件:JWT 与会话」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Ktor 项目设置:embeddedServer 与 Application 模块
  2. 路由与类型化参数
  3. 内容协商与 kotlinx.serialization
  4. 身份验证插件:JWT 与会话
← 返回 Kotlin Academy