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

日志显示重定向成功,为何authorizedRoute仍未按预期响应?

问题分析与解决方案

问题核心

代码在用户信息保存成功后已触发重定向到/authorized,但该路由未执行,无对应日志输出。


相关代码与日志

重定向逻辑

val response = userDataSource.saveUserInfo(user = user)
logger.debug("check response: $response")
if (response) {
    app.log.info("USER SUCCESSFULLY SAVED/RETRIEVED in response sub: $sub, name $name")
    call.sessions.set(UserSession(id = sub, name = name))
    call.respondRedirect("/authorized")
    val redirectLocation = call.response.headers[HttpHeaders.Location]
    logger.debug("Redirected to: $redirectLocation")
} else {
    app.log.info("ERROR SAVING THE USER")
    call.respondRedirect("/unauthorized")
}

日志输出

22:29:14.735 [eventLoopGroupProxy-4-4] INFO  Application - USER SUCCESSFULLY SAVED/RETRIEVED in response sub: 100689333849658126849, name Vadim Morozov
22:29:14.765 [eventLoopGroupProxy-4-4] INFO  Application - 302 Found: POST - /token_verification -> /authorized
22:29:14.765 [eventLoopGroupProxy-4-4] DEBUG io.ktor.util.pipeline.SuspendFunctionGun - Redirected to: /authorized

Authorized路由配置

fun Routing.authorizedRoute() {
    application.log.info("authorizedRoute")
    authenticate("auth-session") {
        get("/authorized") {
            application.log.info("authorizedRoute authorized")
            call.respond(
                message = ApiResponse(success = true),
                status = HttpStatusCode.OK
            )
        }
    }
}

补充配置

认证配置

fun Application.configureAuth() {
    this.log.info("configureAuth")
    install(Authentication) {
        session<UserSession>(name = "auth-session") {
            validate { session ->
                this@configureAuth.log.info("User session: $session")
                session
            }
            challenge {
                this@configureAuth.log.info("User session: unauthorized")
                call.respondRedirect("/unauthorized")
            }
        }
    }
}

Session配置

fun Application.configureSession() {
    this.log.info("configureSession")
    install(Sessions) {
        val secretEncryptKey = hex("00112233445566778899aabbccddeeff")
        val secretAuthKey = hex("02030405060708090a0b0c")
        cookie<UserSession>(
            name = "USER_SESSION",
            storage = directorySessionStorage(File(".sessions"))
        ) {
            transform(SessionTransportTransformerEncrypt(secretEncryptKey, secretAuthKey))
        }
    }
}

Main入口代码

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()
    }
}

问题原因及修复方案

1. 路由未注册

当前module的Routing块仅调用了api函数,未显式注册authorizedRoute。如果api内部没有包含该路由的调用,需手动添加注册:

install(Routing) {
    api(application = application, localSource = localSource)
    authorizedRoute() // 注册authorized路由
}

2. Ktor插件安装顺序错误

Ktor插件依赖顺序严格,Sessions必须在Authentication之前安装(认证依赖会话功能)。当前代码先执行configureAuth()再执行configureSession(),顺序颠倒导致会话无法正常生效,触发认证挑战重定向到/unauthorized,因此/authorized路由从未被执行。

修正顺序:

configureMonitoring()
configureSession() // 先初始化Session
configureAuth()    // 再初始化认证

验证方法

修复后,查看日志是否输出authorizedRoute和authorizedRoute authorized,同时检查认证配置中validate方法是否输出User session相关日志,确认会话与认证正常工作。


内容的提问来源于stack exchange,提问作者Morozov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:34:53