Ktor 从入门到放弃(五) session 管理

作者 : 开心源码 本文共2681个字,预计阅读时间需要7分钟 发布时间: 2022-05-12 共171人阅读

在 Web 开发中 Session 是非常常用也是必要的东西,本篇即来实现在 Ktor 下完成 Session 的操作。

首先我们需要将 Session 安装至框架,在 Ktor 中因为解藕的存在,各个功能均是被安装进去的,在不进行安装的情况下,无法使用 Session(上一篇讲到的 FreeMarker 也需要先安装)。

data class MySession(val name: String, val data: String)@KtorExperimentalAPIfun Application.main() {    install(Sessions) {        cookie<MySession>("CookieName", directorySessionStorage(File(".sessions"))) {            cookie.path = "/"        }    }}

上面的 directorySessionStorage() 来自 Ktor 的 Session 库,并且需要注意的是,directorySessionStorage()也是一个 Experimental 的 API,需要加入注解来使其能够顺利编译:

compile "io.ktor:ktor-server-sessions:$ktor_version"

在上面这段代码里,即表示了这个 Session 可以在文件系统里保存,并且作用范围是全站,即以 / 为路径的所有请求。这意味着我们可以通过请求路径来进行 Session 的隔离。

对于只要要使用 Session,而不需要其余配置的情况下,上面的代码也可以简单的写成:

fun Application.main() {    install(Sessions) {        cookie<MySession>("CookieName")    }}

而后来写一段代码验证一下 Session 的工作情况:

data class MySession(val name: String, val data: String)@KtorExperimentalAPIfun Application.main() {    install(Sessions) {        cookie<MySession>("CookieName", directorySessionStorage(File(".sessions"))) {            cookie.path = "/"        }    }    get("/session") {        val s = call.sessions.get("MySession") as? MySession        if (s == null) {            call.sessions.set("MySession", MySession("rarnu", "init"))            call.respondText { "generated new session" }        } else {            call.respondText { "name: ${s.name}, data: ${s.data}" }        }    }}

编译运行后,在浏览器内访问 http://localhost:8080/session 就可看到效果,第一次进入时,显示 generated new session 而页面刷新后显示 Session 的信息。

同时,我们可以在工程目录下发现被保存下来的 Session 内容:

你可以尝试删掉这个文件看看会发生什么。


在 Ktor 内,拥有几种不同的 Session 管理方式,上面用的是 Cookie,即把数据保存到本地。在很多场景下,我们还会有另外一种请求方式,即把相关的数据放在 Header 里,通常是用于 API 或者 XHR 请求,这个时候我们可以使用 header() 来形容 Session:

fun Application.main() {    install(Sessions) {        header<MySession>("MySession2") {            transform(SessionTransportTransformerMessageAuthentication(SecretKeySpec(key, "HmacSHA256")))        }    }}

这里的 key 是一个 ByteArray 对象,也就是加密用的 key,它可以是任意组合的 byte 串。后面的 HmacSHA256 是采用的算法,具体可以使用哪些算法可以查阅文档。当然此处在文档里有一处 bug,在 Ktor 官方文档内,用于 Header 的 transformSessionTransportTransformerDigest,而这个类并不安全,在 Ktor 内对它的形容如下:

@Deprecated(    "This authentication kind is potentially vulnerable with several hash functions." +        " Use SessionTransportTransformerMessageAuthentication instead or ensure you are using secure enough hash.")

为了安全起见,应当使用此处的 SessionTransportTransformerMessageAuthentication 并配合相应的加密手段。


上面的讲的事情都是在服务器端做的,然而很多时候我们会将 cookie 保存在用户端,这个时候要怎样做呢?其实也很简单的,把上面讲的内容稍做结合即可以了:

fun Application.main() {    install(Sessions) {        cookie<MySession>("CookieName") {            val secretSignKey = hex("000102030405060708090a0b0c0d0e0f")            transform(SessionTransportTransformerMessageAuthentication(secretSignKey))        }    }}

此时我们就拥有了写到用户端的 Cookie 了。当然了,对于用户端 Cookie 有一点很重要,就是校验能否过期,这里也提供一个简单的函数:

data class MySession(val name: String, val expiration: Long)fun ApplicationCall.expiration(): Boolean {    var ret = true    val s = sessions.get(sessionName) as? MySession    if (s != null && System.currentTimeMillis() < s.expiration) {        ret = false    }    return ret}

现在我们可以在 Ktor 程序内自由的使用 Session 了,本篇到此结束。


下一篇预报:《Ktor 从入门到放弃(六) WebSockets》

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Ktor 从入门到放弃(五) session 管理

发表回复