【问题标题】:Scalatra Session without cookies没有 cookie 的 Scalatra 会话
【发布时间】:2012-04-19 08:37:17
【问题描述】:

我正在使用 Scalatra 框架来构建 Web 应用程序。 该应用程序依赖于会话,但我不能使用会话 cookie(因为从技术上讲,只有一个用户,同时运行多个会话)。

每个会话都有一个唯一的会话密钥,我想将其用作标识符。我希望将此密钥作为 GET 或 POST 参数而不是 cookie 标头发送。

我现在的问题是:如何在没有 cookie 的情况下将会话信息(即状态)存储在 Scalatra servlet 中,而只是作为标识符的参数?

到目前为止,我尝试使用文件系统来存储所有会话信息,但这太慢且没有必要,因为会话仅持续几秒钟。

(安全不是问题)

【问题讨论】:

    标签: session scala scalatra


    【解决方案1】:

    我想出了我该怎么做。

    在每个 Scalatra servlet 中,我都可以访问实现 javax.servlet.ServletContext 接口的全局 servletContext。我可以使用它的两种方法setAttribute(x: String, y: Any)getAttribute(x : String) 来存储有关我的会话的信息,其中x 是我的唯一标识符,y 是编码为案例类Session 的会话信息。

    实际上我有以下几点:

    def storeSession(key : String, session : Session) {
        servletContext.setAttribute(attributePrefix + key, session)
    }
    
    def loadSession(key : String) : Session = {
        val session = servletContext.getAttribute(attributePrefix + key)
        if (session != null) {
            session match {
                case s : Session => s
                case _ => null
            }
        } else {
            null
        }
    }
    

    这样我可以在服务器上保持状态,而不使用 cookie,客户端只需提供一个唯一标识符作为 GET 值。

    我想这种技术可以应用于 Java 和 Scala 中提供ServletContext 实例的任何 servlet,而不仅仅是 Scalatra。

    【讨论】:

    • 这是在处理 Java servlet 环境时存储“会话数据”的快速、简单且默认的解决方案——正是我所寻找的。​​span>
    • 如何获得钥匙?会为每个请求生成吗?它如何识别会话?
    • 在我的例子中,使用随机数生成器为每个新会话(不是每个请求)生成密钥。可以使用任何唯一的标识符。
    • 会话因超时而失效怎么办?您是否运行了一些计划任务来检查哪个会话长时间未使用?
    • 在我的情况下,我有一个单独的线程,它会定期删除旧会话(我的会话密钥以时间戳开头,这样我就可以知道它们的年龄),但可能有更好的方法这样做。
    【解决方案2】:

    好问题。

    与其将状态存储到磁盘以及由此带来的性能损失,不如将 Redis 存储在内存中?

    有一个Scala implementation debasishg 是 Scala 社区的重磅人物,它可能符合要求。

    在围栏的无状态方面,例如在 Spray 中,向我建议这是维护状态服务器端的替代方法;即将客户端 cookie 标识符存储到内存缓存与依赖 HttpSession

    【讨论】:

      猜你喜欢
      • 2016-07-02
      • 2011-04-10
      • 2011-04-14
      • 2012-03-08
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多