Ktor Server 中的 Session 身份验证
必需依赖项:io.ktor:ktor-server-auth,io.ktor:ktor-server-sessions
代码示例: auth-form-session
Session 提供了一种在不同 HTTP 请求之间持久化数据的机制。典型用例包括存储已登录用户的 ID、购物车内容或在客户端保留用户偏好。
在 Ktor 中,已经有关联 session 的用户可以使用 session 提供程序进行身份验证。例如,当用户第一次使用 Web 表单登录时,您可以将用户名保存到 cookie session 中,并在后续请求中使用 session 提供程序对该用户进行授权。
您可以在 Ktor Server 中的身份验证与授权章节中获取有关 Ktor 身份验证与授权的一般信息。
添加依赖项
要启用 session 身份验证,您需要在构建脚本中包含以下构件:
添加
ktor-server-sessions依赖项以使用 session:KotlinGroovyXML添加
ktor-server-auth依赖项以进行身份验证:KotlinGroovyXML
Session 身份验证流程
使用 session 的身份验证流程可能会有所不同,这取决于用户在您的应用程序中是如何进行身份验证的。让我们看看使用 基于表单的身份验证时的情形:
- 客户端向服务器发送包含 Web 表单数据(包括用户名和密码)的请求。
- 服务器验证客户端发送的凭据,将用户名保存到 cookie session 中,并返回所请求的内容以及包含用户名的 cookie。
- 客户端携带 cookie 对受保护的资源发起后续请求。
- Ktor 根据接收到的 cookie 数据检查该用户是否存在 cookie session,并可选地对接收到的 session 数据执行额外验证。如果验证成功,服务器将返回所请求的内容。
安装 session 身份验证
要安装 session 身份验证提供程序,请在 install 块内调用带有必需 session 类型的 session 函数:
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.sessions.*
//...
install(Authentication) {
session<UserSession> {
// 配置 session 身份验证
}
}配置 session 身份验证
本节演示了如何使用 基于表单的身份验证对用户进行身份验证,将有关该用户的信息保存到 cookie session 中,然后在后续请求中使用 session 提供程序对该用户进行授权。
有关完整示例,请参阅 auth-form-session。
第 1 步:创建数据类
首先,您需要创建一个用于存储 session 数据的数据类:
@Serializable
data class UserSession(val name: String, val count: Int)第 2 步:安装并配置 session
创建数据类后,您需要安装并配置 Sessions 插件。下面的示例安装并配置了一个带有指定 cookie 路径和过期时间的 cookie session。
install(Sessions) {
cookie<UserSession>("user_session") {
cookie.path = "/"
cookie.maxAgeInSeconds = 60
}
}要了解有关配置 session 的更多信息,请参阅 Session 配置概览。
第 3 步:配置 session 身份验证
session 身份验证提供程序通过 SessionAuthenticationProvider.Config 类公开其设置。在下面的示例中,指定了以下设置:
validate()函数检查 session 实例并在身份验证成功的情况下返回Any类型的项目主体。challenge()函数指定了身份验证失败时执行的操作。例如,您可以重定向回登录页面或发送UnauthorizedResponse。
install(Authentication) {
session<UserSession>("auth-session") {
validate { session ->
if(session.name.startsWith("jet")) {
session
} else {
null
}
}
challenge {
call.respondRedirect("/login")
}
}
}第 4 步:在 session 中保存用户数据
要将已登录用户的信息保存到 session,请使用 call.sessions.set() 函数。
以下示例显示了一个使用 Web 表单的简单身份验证流程:
authenticate("auth-form") {
post("/login") {
val userName = call.principal<UserIdPrincipal>()?.name.toString()
call.sessions.set(UserSession(name = userName, count = 1))
call.respondRedirect("/hello")
}
}有关基于表单的身份验证流程的更多详细信息,请参阅 基于表单的身份验证文档。
第 5 步:保护特定资源
配置好 session 提供程序后,您可以使用 authenticate() 函数保护应用程序中的特定资源。
身份验证成功后,您可以在路由处理程序中使用 call.principal() 函数检索经过身份验证的主体(在本例中为 UserSession 实例):
authenticate("auth-session") {
get("/hello") {
val userSession = call.principal<UserSession>()
call.sessions.set(userSession?.copy(count = userSession.count + 1))
call.respondText("Hello, ${userSession?.name}! Visit count is ${userSession?.count}.")
}
}有关完整示例,请参阅 auth-form-session。
