Ktor中authenticate("auth-session")认证会话不符合预期
Ktor会话认证未按预期工作
问题
使用authenticate("auth-session")包裹路由时,认证会话未生效。请求访问受保护的/authorized路由时,直接触发认证挑战(跳转到/unauthorized),尽管.sessions目录已生成会话文件。调试io.ktor.server.auth的onAuthenticate方法时,发现会话未被保存。
相关配置与代码
主应用配置
internal fun Application.module() { install(Koin) { modules(getKoinModule()) } val localSource by inject<LocalSource>() install(Routing) { api(application = application, localSource = localSource) } configureMonitoring() configureAuth() configureSession() install(StatusPages) { exception<Throwable> { call, cause -> call.respond(cause.toString()) } } install(ContentNegotiation) { json() } }
认证插件配置
fun Application.configureAuth() { this.log.info("configureAuth") install(Authentication) { session<UserSession>(name = "auth-session") { this@configureAuth.log.info("this session: ${this.name}") validate { session -> this@configureAuth.log.info("User session: authorized $session") session } challenge { this@configureAuth.log.info("User session: unauthorized") call.respondRedirect("/unauthorized") } } } }
会话插件配置
fun Application.configureSession() { this.log.info("configureSession") install(Sessions) { val secretEncryptKey = hex("00112233445566778899aabbccddeeff") val secretAuthKey = hex("02030405060708090a0b0c") //6819b57a326945c1968f45236589 cookie<UserSession>( name = "USER_SESSION", storage = directorySessionStorage(File(".sessions")) ) { transform(SessionTransportTransformerEncrypt(secretEncryptKey, secretAuthKey)) } } }
使用的依赖版本
"io.ktor:ktor-server-auth:2.0.3" "io.ktor:ktor-server-sessions:2.0.3"
受保护路由代码
fun Routing.authorizedRoute() { val logger = LoggerFactory.getLogger(javaClass) logger.debug("authorizedRoute here") authenticate("auth-session") { route("/authorized") { get { logger.debug("authorizedRoute authorized GET") call.respond( message = ApiResponse(success = true), status = HttpStatusCode.OK ) } post { logger.debug("authorizedRoute authorized POST") call.respond( message = ApiResponse(success = true), status = HttpStatusCode.OK ) } } } }
会话设置代码
// 登录时设置会话的逻辑 fun Routing.login() { post("/login") { val request = call.receive<LoginRequest>() // 省略用户验证逻辑 val userSession = UserSession(userId = "1", username = request.username) call.sessions.set(userSession) call.respond(ApiResponse(success = true, data = userSession)) } } // UserSession数据类定义 data class UserSession(val userId: String, val username: String)
内容的提问来源于stack exchange,提问作者Morozov
相关产品推荐
相关产品推荐

