Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Web applications 在Ktor 0.9.0 servlet中控制cookie生命周期_Web Applications_Kotlin_Ktor - Fatal编程技术网

Web applications 在Ktor 0.9.0 servlet中控制cookie生命周期

Web applications 在Ktor 0.9.0 servlet中控制cookie生命周期,web-applications,kotlin,ktor,Web Applications,Kotlin,Ktor,删除Ktor 0.9.0服务器端应用程序设置的cookie时遇到问题。也许我不知道如何以正确的方式进行,或者Ktor框架中存在遗漏 Cookie的创建和删除本身不是问题,但是为了删除Cookie,我必须使用与客户端浏览器上的Cookie一起存储的路径。Ktor让我通过创建cookie来控制路径。以下是我的配置: install(Sessions) { cookie<MySession>(sessionMarker) { cookie.duration = co

删除Ktor 0.9.0服务器端应用程序设置的cookie时遇到问题。也许我不知道如何以正确的方式进行,或者Ktor框架中存在遗漏

Cookie的创建和删除本身不是问题,但是为了删除Cookie,我必须使用与客户端浏览器上的Cookie一起存储的路径。Ktor让我通过创建cookie来控制路径。以下是我的配置:

install(Sessions) {
    cookie<MySession>(sessionMarker) {
        cookie.duration = cookieDuration
        cookie.path = "/myWebapp"
        transform(SessionTransportTransformerMessageAuthentication(sessionKey))
    }
}
在客户端上检查时,cookie显示路径
/myWebapp
。默认值为
/myWebapp/page
,因为这是登录页面的路径,但路径取自上面显示的cookie配置。到目前为止一切都很好

最终,用户希望通过登录页面的POST请求注销:

call.sessions.clear<MySession>()
call.sessions.clear()
这里的问题是我没有找到控制cookie路径的方法。因为登录页面
/myWebapp/page/login
正在将过期的cookie发送回客户端以获得另一个路径(它自己的
/myWebapp/page
),所以原始cookie不会被删除(
/myWebapp/page
!=
/myWebapp

在尝试删除cookie时,如何控制它在Ktor 0.9.0中的路径


我知道如何解决这个问题:通过创建具有相同路径的cookie,我将从中删除它。但这不是我想要的(web应用程序中还有其他路径,如
/myWebapp/others
,都应该使用cookie)。在创建过程中控制cookie的路径是没有意义的。

我认为您可以尝试创建自己的自定义SessionTransportCookie

如果您在方法
cookie(sessionMarker)
中看到更深入的内容,您将发现以下代码:

inline fun <reified S : Any> Sessions.Configuration.cookie(name: String, block: CookieSessionBuilder<S>.() -> Unit): Unit = cookie(name, S::class, block)

inline fun <S : Any> Sessions.Configuration.cookie(name: String, sessionType: KClass<S>, block: CookieSessionBuilder<S>.() -> Unit) {
    val builder = CookieSessionBuilder(sessionType).apply(block)
    val transport = SessionTransportCookie(name, builder.cookie, builder.transformers)
    val tracker = SessionTrackerByValue(sessionType, builder.serializer)
    val provider = SessionProvider(name, sessionType, transport, tracker)
    register(provider)
}
因此,正如您所看到的,在这个类中,您可以定制cookies
send/clear
逻辑

inline fun <reified S : Any> Sessions.Configuration.cookie(name: String, block: CookieSessionBuilder<S>.() -> Unit): Unit = cookie(name, S::class, block)

inline fun <S : Any> Sessions.Configuration.cookie(name: String, sessionType: KClass<S>, block: CookieSessionBuilder<S>.() -> Unit) {
    val builder = CookieSessionBuilder(sessionType).apply(block)
    val transport = SessionTransportCookie(name, builder.cookie, builder.transformers)
    val tracker = SessionTrackerByValue(sessionType, builder.serializer)
    val provider = SessionProvider(name, sessionType, transport, tracker)
    register(provider)
}
class SessionTransportCookie(val name: String,
                             val configuration: CookieConfiguration,
                             val transformers: List<SessionTransportTransformer>
) : SessionTransport {

    override fun receive(call: ApplicationCall): String? {
        return transformers.transformRead(call.request.cookies[name])
    }

    override fun send(call: ApplicationCall, value: String) {
        val now = LocalDateTime.now()
        val expires = now.plus(configuration.duration)
        val maxAge = configuration.duration[ChronoUnit.SECONDS].toInt()
        val cookie = Cookie(name,
                transformers.transformWrite(value),
                configuration.encoding,
                maxAge,
                expires,
                configuration.domain,
                configuration.path,
                configuration.secure,
                configuration.httpOnly,
                configuration.extensions
        )

        call.response.cookies.append(cookie)
    }

    override fun clear(call: ApplicationCall) {
        call.response.cookies.appendExpired(name)
    }
}

class CookieConfiguration {
    var duration: TemporalAmount = Duration.ofDays(7)
    var encoding: CookieEncoding = CookieEncoding.URI_ENCODING
    var domain: String? = null
    var path: String? = null
    var secure: Boolean = false
    var httpOnly: Boolean = false
    val extensions: MutableMap<String, String?> = mutableMapOf()
}