You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:29:59